CNContactViewController上的iOS 13.1中的键盘覆盖操作表

mou*_*582 7 swift cncontact cncontactstore cncontactviewcontroller ios13

这似乎特定于iOS 13.1,因为它可以在iOS 13.0和更早版本上按预期工作,并在CNContactViewController中添加联系人,如果我“取消”,则操作表被键盘重叠。没有执行任何操作,也没有关闭键盘。

Gxo*_*ocT 5

我找不到关闭键盘的方法。但至少你可以使用我的方法弹出 ViewController。

  1. 不知道为什么,但在 CNContactViewController 中关闭键盘是不可能的。我尝试了 endEditing:、创建新的 UITextField firstResponder 等等。没有任何效果。
  2. 我试图改变“取消”按钮的动作。您可以在 NavigationController 堆栈中找到此按钮,但是每次键入内容时它的操作都会更改。
  3. 最后我使用了方法调配。如前所述,我找不到关闭键盘的方法,但至少您可以在按下“取消”按钮时关闭 CNContactViewController。
class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        changeImplementation()
    }

    @IBAction func userPressedButton(_ sender: Any) {
        let controller = CNContactViewController(forNewContact: nil)
        controller.delegate = self
        navigationController?.pushViewController(controller, animated: true)
    }

    @objc func popController() {
        self.navigationController?.popViewController(animated: true)
    }

    func changeImplementation() {
        let originalSelector = Selector("editCancel:")
        let swizzledSelector = #selector(self.popController)

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

            method_exchangeImplementations(originalMethod, swizzledMethod)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

PS:您可以找到有关 reddit 主题的其他信息:https : //www.reddit.com/r/swift/comments/dc9n3a/bug_with_cnviewcontroller_ios_131/


Bar*_*ett 5

感谢@GxocT 的出色解决方法!极大地帮助了我的用户。
但我想分享我基于@GxocT 解决方案的代码,希望它能在这种情况下帮助其他人。

我需要CNContactViewControllerDelegate contactViewController(_:didCompleteWith:)被取消(以及完成)。

另外我的代码不在 aUIViewController所以没有self.navigationController

当我可以帮助它时,我也不喜欢使用强制展开。我过去被咬过所以我if let在设置中链接了s

这是我所做的:

  1. CNContactViewControllerswizzle 功能扩展并放置在
    那里。

  2. 在我的调和函数的情况下只需要调用
    CNContactViewControllerDelegate委托
    contactViewController(_:didCompleteWith:)self
    self.contact从接触控制器对象

  3. 在设置代码中,确保 swizzleMethod 调用 class_getInstanceMethod指定了CNContactViewController 类而不是self

和 Swift 代码:

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)
    }
}
Run Code Online (Sandbox Code Playgroud)

键盘仍会暂时显示,但会在 Contacts 控制器关闭后立即下降。
希望苹果解决这个问题