iOS9.0 系统通讯录 ContactsUI/ContactsUI.h

1、在iOS的9.0系统之后,系统的通讯录框架使用了Contacts/Contacts.h,ContactsUI/ContactsUI.h,替换了AddressBook/AddressBook.h,AddressBookUI/AddressBookUI.h,下面就来简单介绍一下ContactsUI/ContactsUI.h的使用
2、ContactsUI/ContactsUI.h是系统自带UI的通讯录界面,我们不用去获取联系人数据,直接利用系统的UI界面就能够展示联系人界面。
3、首先导入头文件

#import 

4、展示界面

// 1.创建通讯录界面(自带系统UI界面)
    CNContactPickerViewController *picketVC = [[CNContactPickerViewController alloc] init]; // 真机或者模拟器的系统版本必须是9.0以上

    // 2.遵守代理 CNContactPickerDelegate
    picketVC.delegate = self;
    // 3.展现通讯录界面
    [self presentViewController:picketVC animated:YES completion:nil];

5、代理方法有5个,iOS9之后系统支持多选和单选2中情况:

// 取消代理方法
- (void)contactPickerDidCancel:(CNContactPickerViewController *)picker;
// 单选代理方法
- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContact:(CNContact *)contact;
- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContactProperty:(CNContactProperty *)contactProperty;
// 多选代理方法
- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContacts:(NSArray<CNContact*> *)contacts;
- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContactProperties:(NSArray<CNContactProperty*> *)contactProperties;

6、带附属属性展示界面
CNContactPickerViewController控制器有几个属性值,分别是(1)displayedPropertyKeys,(2)predicateForEnablingContact,(3)predicateForSelectionOfContact,(4)predicateForSelectionOfProperty
展示界面代码创建如下:

// 1.创建通讯录界面(自带系统UI界面)
    CNContactPickerViewController *picketVC = [[CNContactPickerViewController alloc] init]; // 真机或者模拟器的系统版本必须是9.0以上

    // 2.遵守代理 CNContactPickerDelegate
    picketVC.delegate = self;

    // (1)picketVC.displayedPropertyKeys属性 进入联系人详情界面时需要展示的信息(必须在展示界面之前设置), displayedPropertyKeys不设置的话,会展示所有信息,如果设置的话,则只会根据数组中的信息进行展示,但是这个属性只适用于单选的状态,多选状态下不起作用。

//    picketVC.displayedPropertyKeys = @[CNContactGivenNameKey,CNContactPhoneNumbersKey,CNContactEmailAddressesKey];

    // (2)picketVC.predicateForSelectionOfContact属性 用于控制联系人选中后的操作

//    picketVC.predicateForSelectionOfContact = [NSPredicate predicateWithFormat:@"emailAddresses.@count == 1"];

    // (3)picketVC.predicateForSelectionOfContact属性 用于控制联系人属性选中后的操作

//    picketVC.predicateForSelectionOfProperty = [NSPredicate predicateWithFormat:@"(key == 'emailAddresses') AND (value LIKE '*@mac.com')"]; // 也可以是@qq.com

    // (4)picketVC.predicateForEnablingContact属性 用于控制联系人是否可以选择,如果不设置,默认所有的联系人都是可以交互的(可选中),如果设置了并且命中,则联系人不可交互,不命中的话,可以交互。此属性在多选和单选情况下都起作用
//    picketVC.predicateForEnablingContact = [NSPredicate predicateWithFormat:@"emailAddresses.@count > 0"];

    // 3.展现通讯录界面
    [self presentViewController:picketVC animated:YES completion:nil];

属性是有NSPredicate谓词类创建的,这个可以根据CNContactPickerViewController中属性的表述进行创建,比如NSPredicate *predicateForSelectionOfContact; // e.g. emailAddresses.@count == 1,emailAddresses.@count == 1就是描述字段
7、代理方法的实现
(1)取消代理方法

//点击cancel按钮时被调用(多选状态时,在Done按钮的左侧,单选,多选点击cancel按钮时,都会被调用)
- (void)contactPickerDidCancel:(CNContactPickerViewController *)picker{
    NSLog(@"%s",__func__);
}

// 下面的4个代理方法只需要实现其中的一个就可以,分为单选(一次只能选中一个联系人),多选(同时选中多个联系人)2中情况,如果2种状态同时实现,则多选的优先级比较高,即首先调用多选联系人界面
(2)单选代理方法

/* 如果单选状态下的2个方法同时实现,即实现

    - (void)contactPicker:(CNContactPickerViewController *)picker didSelectContact:(CNContact *)contact;
    - (void)contactPicker:(CNContactPickerViewController *)picker didSelectContactProperty:(CNContactProperty *)contactProperty;

    则第一个方法会优先调用(即第二个方法不会被调用)
    1、只实现第一个方法,点击某一个联系人,则直接会dismiss掉联系人界面
    2、只实现第二个方法,点击某一个联系人会直接进入到联系人详情界面,并且受displayedPropertyKeys属性约束

*/

#pragma mark - 单选
// 只实现这个方法,选中某一个联系人的时候调用,在选中联系人后,联系人界面自动dismiss掉
- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContact:(CNContact *)contact{

    NSLog(@"%s",__func__);

    // 如果picker.predicateForSelectionOfContact没有设置,在选中联系人后,联系人界面自动dismiss掉,此方法会被调用
    // 如果picker.predicateForSelectionOfContact有设置,并且命中了,联系人界面自动dismiss掉,此方法会被调用,如果没有命中,此方法不会被调用,则进入到联系人详情界面(联系人详情界面受displayedPropertyKeys属性约束)

    // 在这里,我选择进入到联系人详情界面,并且详情界面的展示信息不受displayedPropertyKeys属性约束,在选中某一个属性的时候,就会调用系统的操作,比如点击了电话号码,则会直接拨打电话
//    CNContactViewController *vc = [CNContactViewController viewControllerForContact:contact];
//    [self.navigationController pushViewController:vc animated:YES];

}
//
//// 只实现这个方法,点击某一个联系人会直接进入到联系人详情界面,并且受displayedPropertyKeys属性约束,在联系人详情界面中,选中某一个属性的时候调用,在选中属性后,详情界面会自动dismiss掉
- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContactProperty:(CNContactProperty *)contactProperty{

    // 如果picker.predicateForSelectionOfProperty没有设置,在选中联系人后,联系人界面自动dismiss掉,此方法会被调用
    // 如果picker.predicateForSelectionOfProperty有设置,并且命中了,联系人详情界面自动dismiss掉,此方法会被调用,如果没有命中,则此方法不会被调用,联系人详情界面不会dismiss掉(联系人详情界面受displayedPropertyKeys属性约束)

    //在选中某一个属性的时候,如果在方法中不做任何操作的话,则直接会dismiss掉,比如点击了电话号码,则会直接把控制器dismiss,而不是去拨打电话(predicateForSelectionOfProperty没有设置或者设置并命中)。

    NSLog(@"%s",__func__);
    // contactProperty.key(选中属性的键名),contactProperty.value(选中属性的属性,可以根据属性类型进行各种操作)
    NSLog(@"%@,%@",contactProperty.key,contactProperty.value);
}

(3)多选代理方法

#pragma mark - 多选
/* 如果多选状态下的2个方法同时实现,即实现

    - (void)contactPicker:(CNContactPickerViewController *)picker didSelectContacts:(NSArray *)contacts;
    - (void)contactPicker:(CNContactPickerViewController *)picker didSelectContactProperties:(NSArray *)contactProperties;

    则第一个方法会优先调用(即第二个方法不会被调用)
    1、只实现第一个方法,在点击Done按钮的时候则直接会dismiss掉联系人界面
    2、只实现第二个方法,在点击Done按钮的时候则直接会dismiss掉联系人界面
 */

// 只实现这个方法,只要点击done之后,就会被调用(选中联系人的时候或者没有选择的时候都会),联系人界面会自动dismiss掉
//- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContacts:(NSArray *)contacts{
//    
//    // predicateForSelectionOfContact,predicateForSelectionOfProperty属性 不影响
//
//    NSLog(@"%s,%lu",__func__,contacts.count);
//    
////    CNContactViewController *vc = [CNContactViewController viewControllerForContact:[contacts lastObject]];
////    [self.navigationController pushViewController:vc animated:YES];
//    
//}


// 只实现这个方法,选中联系人的时候被调用(可以多选)点击done之后,联系人界面会自动dismiss掉
//- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContactProperties:(NSArray *)contactProperties{
//
//    NSLog(@"%s",__func__);
//    NSLog(@"%@,%@",[contactProperties lastObject].key,[contactProperties lastObject].value);
//    // picker.predicateForSelectionOfContact属性 不影响
//    // 如果picker.predicateForSelectionOfProperty没有设置,所有的联系人都可以被选中
//    // 如果picker.predicateForSelectionOfProperty有设置,并且命中了,联系人能被选中,不命中的话不能被选中
//
//}

在除了取消代理方法外的其余4个方法,只要实现一个就可以了,如果同时实现多选和单选代理方法,则多选代理的优先级比较高,如果同时实现单选(多选)代理方法,则选择联系人的方法优先级高。
8、有关属性对代理的一些影响,已经在代理方法中描述过了,可能描述的还不是太清晰,可能还有错误的地方,建议大家把属性设置出来,多测试一下,有关联系人的创建,修改等操作,会在后续的文档中写出来,需要对大家有帮助。
9、相关的截图就不上传了,大家可以直接复制代码,运行就可以看到效果。

你可能感兴趣的:(iOS系统框架知识点)