【问题标题】:CNContactViewControllerDelegate not called when contact property selected/edited on iOS在 iOS 上选择/编辑联系人属性时未调用 CNContactViewControllerDelegate
【发布时间】:2018-12-04 00:52:03
【问题描述】:

编辑或选择属性时不会调用CNContactviewController 的委托。

在编辑新联系人时,应该调用contactViewController(_ viewController: CNContactViewController, shouldPerformDefaultActionFor property: CNContactProperty) 函数,但实际上没有。

当用户编辑/选择联系人属性时,您如何获得通知?

重现步骤:

  1. 复制下面的视图控制器。
  2. 编辑/选择联系人 财产。

预期行为:

每次编辑/选择属性时都会打印“yo”。

实际行为:

什么都没有。

import Foundation
import Contacts
import ContactsUI


class ContactViewController: UIViewController, CNContactViewControllerDelegate {


    override func viewDidLoad() {
        super.viewDidLoad()

        createContact()
    }


    func createContact() {
        let contactController = CNContactViewController(forNewContact: nil)

        contactController.delegate = self
        contactController.allowsEditing = true
        contactController.allowsActions = true
        contactController.displayedPropertyKeys = [CNContactPostalAddressesKey, CNContactPhoneNumbersKey, CNContactGivenNameKey]

        contactController.view.layoutIfNeeded()

        present(contactController, animated:true)
    }


    // =============================================================================================================
    // MARK: CNContactViewControllerDelegate Functions
    // =============================================================================================================
    func contactViewController(_ viewController: CNContactViewController, didCompleteWith contact: CNContact?) {
        viewController.dismiss(animated: true, completion: nil)
        print("hi")
    }


    func contactViewController(_ viewController: CNContactViewController, shouldPerformDefaultActionFor property: CNContactProperty) -> Bool {
        print("yo")
        return true
    }


    // =============================================================================================================
    // MARK: UIViewController Functions
    // =============================================================================================================
    override var prefersStatusBarHidden: Bool {
        return true
    }


    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

【问题讨论】:

    标签: ios swift contacts cncontact


    【解决方案1】:

    制作 CNContactViewController 有三个初始化器:

    • 现有联系人:init(for:)
    • 新联系人:init(forNewContact:)
    • 未知联系人:init(forUnknownContact:)

    第一种和第三种形式调用委托方法contactViewController(_:shouldPerformDefaultActionFor:)。第二种形式没有。那就是你正在使用的那个。

    使用第二种风格,您获得的唯一事件是contactViewController(_:didCompleteWith:),此时新联系人已保存到数据库中。

    在编辑新联系人时,应该调用contactViewController(_ viewController: CNContactViewController, shouldPerformDefaultActionFor property: CNContactProperty)函数

    不,不是。这只是你的想法。

    预期行为:每次编辑/选择属性时都会打印“yo”。

    那就别期待了。

    当用户编辑/选择联系人属性时,您如何获得通知?

    你没有。

    当您使用 Cocoa 之类的框架时,您无法做出任何您喜欢的期望。您的期望需要基于框架的实际作用。您可能希望 CNContactViewController 及其委托消息如您所描述的那样工作,这可能会向 Apple 提出非常好的增强请求。但这不是它的工作原理事实上,所以期望它这样做对你没有任何好处。

    【讨论】:

    • 好的,谢谢。文档contactViewController(_:shouldPerformDefaultActionFor:) 非常稀少。那么这个函数有什么作用呢?有没有办法知道用户是否更改了联系人属性?再次感谢!
    • 嗯,整个问题对我来说没有多大意义。使用init(forNewContact:),您要求用户创建新联系人。知道用户何时完成该任务是没有意义的。用户是否创建了新联系人,当它结束时你会发现它的所有信息。知道用户在中间做什么有什么用?不过,正如我所说,如果您有一个好的用例,请将其提交给 Apple。更令我不安的是,当您收到任何事件时,联系人已经保存到数据库中,您无法阻止。
    • 感谢您的回复。目标是重用联系表单,因为它具有地址和电话号码的本地化逻辑,然后将联系信息存储在其他地方。这不是用于在用户的通讯录中存储联系人,而是在应用程序的。
    • 是的,这就是我刚才提到的问题:没有为您提供任何接口来执行此操作。你能做的最好的就是在用户存储后立即从数据库中删除联系人(我就是这样做的)。
    • 好的,谢谢!碰巧,您知道是否可以在编辑期间仅显示部分字段(例如,地址、电话)?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-02-05
    • 2012-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多