Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

This seems to be specific to iOS 13.1, as it works as expected on iOS 13.0 and earlier versions to add a contact in CNContactViewController, if I 'Cancel', the action sheet is overlapping by keyboard. No actions getting performed and keyboard is not dismissing.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
819 views
Welcome To Ask or Share your Answers For Others

1 Answer

Kudos to @GxocT for the the great workaround! Helped my users immensely.
But I wanted to share my code based on @GxocT solution hoping it will help others in this scenario.

I needed my CNContactViewControllerDelegate contactViewController(_:didCompleteWith:) to be called on cancel (as well as done).

Also my code was not in a UIViewController so there is no self.navigationController

I also dont like using force unwraps when I can help it. I have been bitten in the past so I chained if lets in the setup

Here's what I did:

  1. Extend CNContactViewController and place the swizzle function in
    there.

  2. In my case in the swizzle function just call the
    CNContactViewControllerDelegate delegate
    contactViewController(_:didCompleteWith:) with self and
    self.contact object from the contact controller

  3. In the setup code, make sure the swizzleMethod call to class_getInstanceMethod specifies the CNContactViewController class instead of self

And the Swift code:

class MyClass: CNContactViewControllerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        self.changeImplementation()
    }

    func changeCancelImplementation() {

        let originalSelector = Selector(("editCancel:"))
        let swizzledSelector = #selector(CNContactViewController.cancelHack)

        if let originalMethod = class_getInstanceMethod(object_getClass(CNContactViewController()), originalSelector),
           let swizzledMethod = class_getInstanceMethod(object_getClass(CNContactViewController()), swizzledSelector) {

            method_exchangeImplementations(originalMethod, swizzledMethod)
        }
    }

   func contactViewController(_ viewController: CNContactViewController, didCompleteWith contact: CNContact?) {
       // dismiss the contacts controller as usual
       viewController.dismiss(animated: true, completion: nil)
       // do other stuff when your contact is canceled or saved
       ...
    }
}

extension CNContactViewController {
    @objc func cancelHack()  {
        self.delegate?.contactViewController?(self, didCompleteWith: self.contact)
    }
}

The keyboard still shows momentarily but drops just after the Contacts controller dismisses.
Lets hope apple fixes this


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...