当我使用没有与之关联的数字的CNContactPickerViewController
选择联系人时,永远不会调用此委托方法。
/*!
* @abstract Invoked when the picker is closed.
* @discussion The picker will be dismissed automatically after a contact or property is picked.
*/
optional public func contactPickerDidCancel(picker: CNContactPickerViewController)
如果我选择一个有号码的联系人,则会调用它。但是从方法文档来看,无论如何都应该调用它。
我的问题是,如果用户选择没有号码的联系人,我需要提供UIAlertController
。但是,我只能在CNContactPickerViewController
被解雇后才能这样做。
我可以通过在viewDidAppear
中使用一些逻辑来变得非常hacky,但似乎应该有一个更清洁的方式。
唯一剩下的委托方法是:
/*!
* @abstract Singular delegate methods.
* @discussion These delegate methods will be invoked when the user selects a single contact or property.
*/
optional public func contactPicker(picker: CNContactPickerViewController, didSelectContact contact: CNContact)
optional public func contactPicker(picker: CNContactPickerViewController, didSelectContactProperty contactProperty: CNContactProperty)
/*!
* @abstract Plural delegate methods.
* @discussion These delegate methods will be invoked when the user is done selecting multiple contacts or properties.
* Implementing one of these methods will configure the picker for multi-selection.
*/
optional public func contactPicker(picker: CNContactPickerViewController, didSelectContacts contacts: [CNContact])
optional public func contactPicker(picker: CNContactPickerViewController, didSelectContactProperties contactProperties: [CNContactProperty])
这对确定CNContactPickerViewController
实际离开屏幕的时间没有帮助。
(Xcode8 / swift2.3 / iOS10)
答案 0 :(得分:3)
您可以弹出这样的提醒。您还可以添加一个按钮以“再试一次”并重新启动选择器。
func contactPicker(_ picker: CNContactPickerViewController, didSelect contact: CNContact) {
let name = CNContactFormatter.string(from: contact, style: .fullName)
let phones = contact.phoneNumbers
if phones.count == 0 {
let alertController = UIAlertController(title: "Error", message: "\(name) has no phone numbers", preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "Ok", style: .default) { (action) in })
picker.dismiss(animated: false){
self.present(alertController, animated: true) {}
}
}
//Do stuff here
}
答案 1 :(得分:1)
我同意您似乎很奇怪,当您自行关闭选择器时,需要以编程方式将其关闭。顺便说一句,对于macOS,您需要委托方法:
- (void)contactPickerWillClose:(CNContactPicker *)picker; // In macOS, called when the contact picker’s popover is about to close.
- (void)contactPickerDidClose:(CNContactPicker *)picker; // In macOS, called when the contact picker’s popover has closed.
无论如何,由于某些原因,这些委托方法不适用于iOS开发人员。这是解决这种情况的另一种方法:由于CNContactPickerViewController
是UIViewController
类的后代,因此它自动具有以下方法:
- (void)viewWillDisappear:(BOOL)animated; // Called when the view is dismissed, covered or otherwise hidden. Default does nothing
- (void)viewDidDisappear:(BOOL)animated; // Called after the view was dismissed, covered or otherwise hidden. Default does nothing
需要创建您自己的这些方法的实现,这些实现将使用委托来告诉您CNContactPickerViewController
View
是被解雇还是将被解雇。这是我的此类实现的Objective-C示例:
SKContactPickerViewController.h
#import <ContactsUI/ContactsUI.h>
@protocol SKContactPickerDelegate;
@interface SKContactPickerViewController : CNContactPickerViewController
@property (weak, nonatomic, nullable) id <CNContactPickerDelegate, SKContactPickerDelegate> delegate;
@end
@protocol SKContactPickerDelegate <CNContactPickerDelegate>
@required
- (void)contactPicker:(SKContactPickerViewController *)picker viewDidDisappear:(BOOL)animated;
@optional
- (void)contactPicker:(SKContactPickerViewController *)picker viewWillDisappear:(BOOL)animated;
@end
SKContactPickerViewController.m
#import "SKContactPickerViewController.h"
@implementation SKContactPickerViewController
@dynamic delegate;
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
SEL selector = @selector(contactPicker:viewWillDisappear:);
if ([self.delegate respondsToSelector:selector]) {
[self.delegate contactPicker:self
viewWillDisappear:animated];
}
}
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
SEL selector = @selector(contactPicker:viewDidDisappear:);
if ([self.delegate respondsToSelector:selector]) {
[self.delegate contactPicker:self
viewDidDisappear:animated];
}
}
@end
.m文件中使用联系人选择器的位置:
- (void)addFromContacts {
SKContactPickerViewController *contactPicker = [[SKContactPickerViewController alloc] init];
contactPicker.delegate = self;
// contactPicker.displayedPropertyKeys = @[CNContactEmailAddressesKey];
// etc.
// display controller
[self presentViewController:contactPicker
animated:YES
completion:nil];
}
最后是委托方法:
- (void)contactPicker:(SKContactPickerViewController *)picker didSelectContact:(CNContact *)contact {
// your usual implementation
}
- (void)contactPicker:(SKContactPickerViewController *)picker viewDidDisappear:(BOOL)animated {
// Present your UIAlertController here
}
在关闭联系人选择器后,将允许显示UIAlsertController
。同样,这种方法仍然使您能够使用常规的委托方法从Contacts UI中获取数据-委托属性仍来自Apple实现。即@dynamic delegate;
用于表示此属性将由其超类实现。您只需使用两个添加的方法通过自己的CNContactPickerDelegate
扩展SKContactPickerDelegate
协议即可。