我试图从通讯簿中选择联系人号码,当我试图修改其逻辑时,它未能选择通讯簿,相反,当我单击该号码时,它正在调用该号码。当我试图选择号码时,代表团没有被调用。
下面的代码虽然很长,但是我试图描述所有的内容(省略不相关的代码),所以您可以理解这个问题。
所以,复杂的事情是,我有一个HomeViewController,我从一个名为HomeHelper的助手(一个带UITableView的UIView)中设置所有数据。我确实从一个名为WidgetView的视图添加了UITableViewCell,并且数据是从WidgetHelper设置的。WidgetHelper将加载名为WidgetProductAHelper的UITableViewCell(以及名为WidgetProductAView的视图)。
WidgetProductAView包含一个图像按钮,当我单击该按钮时,它应该会显示联系人选取器。我尝试将逻辑分离到一个名为AddressBookHelper的新类,这样我就可以在任何地方使用它,而无需任何冗余。它确实成功地显示了地址簿,但是当我尝试单击其中一个地址簿时,它将重定向到详细联系人屏幕,而不是调用peoplePickerNavigationController的方法。我已经安排了代表团,但仍然没有成功。
当我试着只在一节课上写的时候,这些东西确实有效。怎么了?请帮忙弄清楚,我怀疑在使用helpers上有一些不正确的实现,但无法弄清楚。谢谢。
homewiewcontroller.swift主页视图控制器
class HomeViewController: UIViewController {
var dataSource : UITableViewDataSource?
var delegate : UITableViewDelegate?
override func viewDidLoad() {
//
let helper = HomeHelper()
helper.homeViewController = self
dataSource = helper
delegate = helper
tableView.dataSource = dataSource
tableView.delegate = delegate
}
}
家庭助手.swift
class HomeHelper: UITableViewDataSource, UITableViewDelegate, WidgetViewDelegate {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "WidgetView", for: indexPath) as? UITableViewCell else {
return UITableViewCell()
}
if let customView = cell.customView as? WidgetView {
let helper = WidgetHelper()
customView.helperDataSource = helper
customView.helperDelegate = helper
customView.delegate = self
helper.controller = customView
customView.initCell()
return cell
}
}
// MARK: - WidgetViewDelegate
func presentOnHome(_ viewControllerToPresent: UIViewController, animated: Bool, completion: (() -> Swift.Void)? = nil) {
self.homeViewController?.present(viewControllerToPresent, animated: animated, completion: completion)
}
}
WidgetView.swift网站
protocol WidgetViewDelegate {
func presentOnHome(_ viewControllerToPresent: UIViewController, animated: Bool, completion: (() -> Swift.Void)?)
}
class WidgetView: NSObject {
var delegate: WidgetViewDelegate?
var helperDataSource: WidgetViewHelperDataSource?
var helperDelegate: WidgetViewHelperDelegate?
func initCell() {
//
tableView.dataSource = helperDataSource
tableView.delegate = helperDelegate
}
func presentOnHome(_ viewControllerToPresent: UIViewController, animated: Bool, completion: (() -> Swift.Void)?) {
delegate?.presentOnHome(viewControllerToPresent, animated: animated, completion: completion)
}
}
widgetshelper.swift网站
class WidgetHelper: UITableViewDataSource, UITableViewDelegate, WidgetProductAHelperDelegate {
var controller: WidgetView?
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "WidgetProductAView", for: indexPath) as? UITableViewCell else {
return UITableViewCell()
}
if let customView = cell.customView as? WidgetProductAHelper {
customView.parentHelper = self
customView.delegate = self
customView.initCell()
return cell
}
}
// MARK: - WidgetProductAHelperDelegate
func presentOnHome(_ viewControllerToPresent: UIViewController, animated: Bool, completion: (() -> Swift.Void)? = nil) {
self.homeViewController?.present(viewControllerToPresent, animated: animated, completion: completion)
}
}
WidgetProductAHelper.swift公司
protocol WidgetProductAHelperDelegate {
func presentOnHome(_ viewControllerToPresent: UIViewController, animated: Bool, completion: (() -> Swift.Void)?)
}
class WidgetProductAHelper: UITableViewDataSource, UITableViewDelegate {
@IBOutlet var contactImageButton: UIButton!
var parentHelper: WidgetHelper?
var delegate: WidgetProductAHelperDelegate?
}
func initCell() {
//
contactImageButton.isUserInteractionEnabled = true;
contactImageButton.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(WidgetProductAHelper.contactImageButtonTapped(_:))))
}
func contactImageButtonTapped(_ sender: UIGestureRecognizer) {
let addressBookHelper = AddressBookHelper()
addressBookHelper.contactImageButton = contactImageButton
addressBookHelper.completion = { (result) in
switch result {
case .presentOnHome(let viewControllerToPresent) :
self.parentHelper?.presentOnHome(viewControllerToPresent, animated: true, completion: nil)
break
}
}
addressBookHelper.addressBookButtonTapped()
}
地址bookhelper.swift
正如您在下面的代码中看到的,我已经将CNPicker的委托设置为类,但是没有调用委托的方法。对于displayErrorMessage()和displayPromptForAddressBookRequestAccess()等其他内容,它在显示弹出窗口时效果很好。
enum AddressBookActionResult {
case presentOnHome(viewControllerToPresent: UIViewController)
}
class AddressBookHelper: NSObject, CNContactPickerDelegate {
var completion: ((AddressBookActionResult) -> ())?
var contactImageButton: UIButton?
@available(iOS 9.0, *)
var CNPicker: CNContactPickerViewController {
return CNContactPickerViewController()
}
func addressBookButtonTapped() {
switch CNContactStore.authorizationStatus(for: .contacts) {
case .denied, .restricted:
// displayErrorMessage()
break
case .authorized:
openUserAddressBook()
break
case .notDetermined:
// displayPromptForAddressBookRequestAccess()
break
}
}
func openUserAddressBook() {
if #available(iOS 9.0, *) {
CNPicker.delegate = self
completion?(.presentOnHome(viewControllerToPresent: CNPicker))
}
}
// MARK: - CNContactPickerDelegate
@available(iOS 9.0, *)
func contactPicker(_ picker: CNContactPickerViewController, didSelect contact: CNContact) {
// This method doesn't get called
//...
}
}
最佳答案
看看这个函数:
func openUserAddressBook() {
let CNPicker: CNContactPickerViewController = CNContactPickerViewController()
CNPicker.delegate = self
completion?(.presentOnHome(viewControllerToPresent: CNPicker))
}
您在该函数中创建了
CNPicker
,并且一旦退出openUserAddressBook
函数,CNPicker
就会被释放。最好将
CNPicker
设置为位于AddressBookHelper顶部的属性。例如。:
class AddressBookHelper: NSObject, CNContactPickerDelegate {
// create CNContactPickerViewController once and only once
let cnPicker = CNContactPickerViewController()
var completion: ((AddressBookActionResult) -> ())?
override init()
{
super.init()
// and set the delegate of the picker to this Helper class
self.cnPicker.delegate = self
}
func openUserAddressBook() {
completion?(.presentOnHome(viewControllerToPresent: self.cnPicker))
}
func contactPicker(_ picker: CNContactPickerViewController,
didSelect contact: CNContact)
{
print("selected a contact!")
}
// and other delegate methods can be implemented and they
// will be called...
}
关于ios - 联系人选择器的委派设置不正确,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46744278/