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 <ContactsUI/ContactsUI.h>

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<CNContact*> *)contacts;
    - (void)contactPicker:(CNContactPickerViewController *)picker didSelectContactProperties:(NSArray<CNContactProperty*> *)contactProperties;

    則第一個方法會優先調用(即第二個方法不會被調用)
    1、只實現第一個方法,在點擊Done按鈕的時候則直接會dismiss掉聯繫人界面
    2、只實現第二個方法,在點擊Done按鈕的時候則直接會dismiss掉聯繫人界面
 */

// 只實現這個方法,只要點擊done之後,就會被調用(選中聯繫人的時候或者沒有選擇的時候都會),聯繫人界面會自動dismiss掉
//- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContacts:(NSArray<CNContact*> *)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<CNContactProperty*> *)contactProperties{
//
//    NSLog(@"%s",__func__);
//    NSLog(@"%@,%@",[contactProperties lastObject].key,[contactProperties lastObject].value);
//    // picker.predicateForSelectionOfContact屬性 不影響
//    // 如果picker.predicateForSelectionOfProperty沒有設置,所有的聯繫人都可以被選中
//    // 如果picker.predicateForSelectionOfProperty有設置,並且命中了,聯繫人能被選中,不命中的話不能被選中
//
//}

在除了取消代理方法外的其餘4個方法,只要實現一個就可以了,如果同時實現多選和單選代理方法,則多選代理的優先級比較高,如果同時實現單選(多選)代理方法,則選擇聯繫人的方法優先級高。
8、有關屬性對代理的一些影響,已經在代理方法中描述過了,可能描述的還不是太清晰,可能還有錯誤的地方,建議大家把屬性設置出來,多測試一下,有關聯繫人的創建,修改等操作,會在後續的文檔中寫出來,需要對大家有幫助。
9、相關的截圖就不上傳了,大家可以直接複製代碼,運行就可以看到效果。

發佈了44 篇原創文章 · 獲贊 16 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章