分析开发者指南源码 GIT地址 https://github.com/iimgal/StudyiOS
通讯录
知识重点:
1
AddressBookUI中提供了和联系人显示信息相关的一些Controller,有四个:
ABPeoplePickerNavigationController:显示整个通讯录并可以选择一个联系人的信息
ABPersonViewController:显示一个具体联系人的信息
ABNewPersonViewController:增加一个新的联系人
ABUnknownPersonViewController:完善一个联系人的信息
2
viewDidLoad其实没什么可混淆的,无论通过什么途径加载(Xcode或者IB,这里的加载属于实例化)完view后肯定会执行这个方法.
loadView需要分两种情况.当你通过Xcode实例化一个类的时候就需要自己在controller中实现这个方法.而在IB中实例化就不需要实现它.
initWithNibName这个方法是在controller的类在IB中创建,但是通过Xcode实例化controller的时候用的.
awakeFromNib是类在IB中被实例化调用.推荐使用viewDidLoad,因为viewDidLoad会被多次调用,而awakeFromNib只会当从nib文件中unarchive的时候才会被调用一次,awakeFromNib被调用时,viewDidLoad不会被调用
当.nib文件被加载的时候,会发送一个awakeFromNib的消息到.nib文件中的每个对象,每个对象都可以定义自己的awakeFromNib函数来响应这个消息,也就是说通过nib文件创建view对象来执行awakeFromNib
当view对象被加载到内存是就会执行viewDidLoad,所以不管通过nib文件还是代码的方式创建对象都会执行viewDidLoad
3.
UIBarButtonItem 工具栏按钮有3种主要的定制方法:1、在Interface builder中定制;2、setItems方法定制;3、addSubview方法定制。
UIBarButtonItem * clearnButton = [UIBarButtonItem alloc] initWithTitle:@"Code" style:UIBarButtonItemStyleBordered target:self action:@selector(code)]; 初始化
NSArray *buttonArray = [[NSArray alloc]initWithObjects:cleanButton,saveButton, nil];
self.navigationItem.rightBarButtonItems = buttonArray; 多按钮用法
4、
[super class] 先转换成 objc_msgSendSuper 的方法。构造 objc_super 的结构体
id objc_msgSendSuper(struct objc_super *super, SEL op, ...)
struct objc_super {
id receiver;
Class superClass;
};
shouldAutorotateToInterfaceOrientation 自动旋转功能
5、
ABPeoplePickerNavigationController 系统的通讯录控件
ABPeoplePickerNavigationController *picker = [[ABPeoplePickerNavigationController alloc] init];
picker.peoplePickerDelegate = self; //初始化
6、
__bridge只做类型转换,但是不修改对象(内存)管理权;
__bridge_transfer(也可以使用CFBridgingRelease)将Core Foundation的对象转换为Objective-C的对象,同时将对象(内存)的管理权交给ARC。
7、
__bridge_retained(也可以使用CFBridgingRetain)将Objective-C的对象转换为Core Foundation的对象,同时将对象(内存)的管理权交给我们,后续需要使用CFRelease或者相关方法来释放对象
8、
UIAlertView常用于应用界面信息警告提示
9、
ABRecordRef 一个指向Core Foundation对象的通用指针
10、
ABMultiValueCreateMutable 返回一个新的,空的,可变的多值属性
ABMultiValueAddValueAndLabel 添加到多值属性的值及其对应的标签
ABRecordSetValue(aContact, kABPersonEmailProperty, email, &anError); 添加单个项的属性值
ContactViewController.h 头文件
#import <UIKit/UIKit.h>
//基库,一系列的Class(类)来建立和管理iPhone OS应用程序的用户界面接口、应用程序对象、事件控制、绘图模型、窗口、视图和用于控制触摸屏等的接口
#import <AddressBook/AddressBook.h>
//地址薄框架提供联系人数据库,通讯数据库等
#import <AddressBookUI/AddressBookUI.h>
//地址薄UI框架提供编辑,选择,创建通讯数据库
#import "IIAddressBook.h"
//提供解析通讯录数据的一系列方法
@interface ContactViewController : UIViewController<ABPeoplePickerNavigationControllerDelegate,
ABNewPersonViewControllerDelegate,
ABPersonViewControllerDelegate,
ABUnknownPersonViewControllerDelegate>
/**
委托接口主要功能
ABPeoplePickerNavigationController:显示整个通讯录并可以选择一个联系人的信息
ABPersonViewController:显示一个具体联系人的信息
ABNewPersonViewController:增加一个新的联系人
ABUnknownPersonViewController:完善一个联系人的信息
**/
@property (nonatomic, strong) IBOutlet UILabel *label;
/*
多线程,strong<>IBOutlet引用计数加2,IBOutlet<>IB控件关联
监听中间区域 lable文本
*/
/**
IBAction<>IB控件动作相关联
**/
- (IBAction)showPeoplePickerController; //监听查看按钮
- (IBAction)showNewPersonViewController;//监听新增按钮
- (IBAction)showPersonViewController; //监听编辑按钮
- (IBAction)showUnknownPersonViewController;//监听未知按钮
@end
ContactViewController.m
#import "ContactViewController.h"
@implementation ContactViewController
//合成器
@synthesize label;
/**
手动初始化ViewController nibNameOrNil 直需要文件名,无需扩展即contact(.nib不需要)
**/
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
//初始化父类ViewController
if (self) {
// Custom initialization
}
return self; //跳出
}
/**
当内存不足时,释放不需要的内存,缓存,未显示的view等
**/
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
/*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView
{
}
*/
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
/**
视图加载时调用
**/
- (void)viewDidLoad
{
// 增加Code按钮,可跳转至教学页面
//初始化一个新的按钮,使用指定的标题,样式,目标(自己还是其他view视图),出口方法。
UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithTitle:@"Code" style:UIBarButtonItemStyleBordered target:self action:@selector(code)];
//设置按钮到右侧
self.navigationItem.rightBarButtonItem = item;
//初始化
[super viewDidLoad];
}
/**
当内存不足时,最大程度释放内存
**/
- (void)viewDidUnload
{
self.label = nil; //重置lable
[super viewDidUnload]; //释放内存
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
/**
是否支持iphone 旋转
**/
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
//系统默认不支持旋转功能
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark -
#pragma mark Show all contacts
// Called when users tap "Display Picker" in the application. Displays a list of contacts and allows users to select a contact from that list.
// The application only shows the phone, email, and birthdate information of the selected contact.
/**
查看联系人数据
1、先初始化系统通讯控件
2、设置需要显示的信息,手机等
3、用presentModalViewController 呈现
**/
-(void)showPeoplePickerController
{
// 查看联系人 系统的通讯录控件
ABPeoplePickerNavigationController *picker = [[ABPeoplePickerNavigationController alloc] init];
picker.peoplePickerDelegate = self; //委托给自己
// Display only a person's phone, email, and birthdate
/**
消息设置版
[picker setDisplayedProperties:[NSArray arrayWithObjects:[NSNumber numberWithInt:kABPersonPhoneProperty],
[NSNumber numberWithInt:kABPersonEmailProperty],
[NSNumber numberWithInt:kABPersonBirthdayProperty], nil]];
//属性版
picker.displayedProperties = NSArray arrayWithObjects:[NSNumber numberWithInt:kABPersonPhoneProperty],
[NSNumber numberWithInt:kABPersonEmailProperty],
[NSNumber numberWithInt:kABPersonBirthdayProperty], nil];
*/
//将手机,邮箱,生日数据压入数组
NSArray *displayedItems = [NSArray arrayWithObjects:[NSNumber numberWithInt:kABPersonPhoneProperty],
[NSNumber numberWithInt:kABPersonEmailProperty],
[NSNumber numberWithInt:kABPersonBirthdayProperty], nil];
//设置需要显示的数据
picker.displayedProperties = displayedItems;
// Show the picker
//显示数据 使用 presentModalViewController可创建新视图,可用于视图之间的切换
[self presentModalViewController:picker animated:YES];
}
#pragma mark Display and edit a person
// Called when users tap "Display and Edit Contact" in the application. Searches for a contact named "Appleseed" in
// in the address book. Displays and allows editing of all information associated with that contact if
// the search is successful. Shows an alert, otherwise.
/**
编辑地址薄数据
1、ABAddressBookCreate 得到地址薄
2、查找是否有张三数据
3、如果没有提示用户,有则进入编辑视图
**/
-(void)showPersonViewController
{
// 得到地址薄 iphone6.0不推荐使用
ABAddressBookRef addressBook = ABAddressBookCreate();
// 寻找名为“CC”的联系人
NSArray *people = (__bridge NSArray *)ABAddressBookCopyPeopleWithName(addressBook, CFSTR("zhangsan"));
// Display "Appleseed" information if found in the address book
//如果有数据
if ((people != nil) && [people count])
{
//ABRecordRef 一个指向Core Foundation对象的通用指针
ABRecordRef person = (__bridge ABRecordRef)[people objectAtIndex:0];
ABPersonViewController *picker = [[ABPersonViewController alloc] init]; //初始化
picker.personViewDelegate = self;
picker.displayedPerson = person;
//精简版 picker.displayedPerson = (__bridge ABRecordRef)[people objectAtIndex:0];
// Allow users to edit the person’s information
picker.allowsEditing = YES;
//更新联系人数据到编辑视图
[self.navigationController pushViewController:picker animated:YES];
}
else //没有数据则给一些提示信息
{
// Show an alert if "Appleseed" is not in Contacts
//UIAlertView常用于应用界面信息警告提示
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error"
message:@"Could not find 张三 in the Contacts application"
delegate:nil
cancelButtonTitle:@"Cancel"
otherButtonTitles:nil];
[alert show]; //弹出提示
}
CFRelease(addressBook); //释放
}
#pragma mark Create a new person
// Called when users tap "Create New Contact" in the application. Allows users to create a new contact.
/**
创建新的联系人
1、初始化系统的新增联系人控件
2、新建一个导航控制器
3、创建新视图
**/
-(void)showNewPersonViewController
{
// 初始化系统的新增联系人控件
ABNewPersonViewController *picker = [[ABNewPersonViewController alloc] init];
picker.newPersonViewDelegate = self;
//新建一个导航控制器
UINavigationController *navigation = [[UINavigationController alloc] initWithRootViewController:picker];
//创建新视图,可用于视图之间的切换
[self presentModalViewController:navigation animated:YES];
}
#pragma mark Add data to an existing person
// Called when users tap "Edit Unknown Contact" in the application.
/**
当点击未知联系人
1、初始化联系人数据库连接
2、添加多项属性,以及单独设置各项属性值
3、设置联系人数据
4、创建新视图
**/
-(void)showUnknownPersonViewController
{
// 打开联系人数据库 iphone6.0不推荐使用
ABRecordRef aContact = ABPersonCreate();
CFErrorRef anError = NULL;
//返回一个新的,空的,可变的多值属性
ABMultiValueRef email = ABMultiValueCreateMutable(kABMultiStringPropertyType);
//添加到多值属性的值及其对应的标签。
bool didAdd = ABMultiValueAddValueAndLabel(email, @"John-Appleseed@mac.com", kABOtherLabel, NULL);
if (didAdd == YES) //添加成功
{
//添加单个项的属性值,如邮箱. int32_t ABPropertyID
ABRecordSetValue(aContact, kABPersonEmailProperty, email, &anError);
if (anError == NULL)
{
//设置联系人数据
ABUnknownPersonViewController *picker = [[ABUnknownPersonViewController alloc] init];
picker.unknownPersonViewDelegate = self;
picker.displayedPerson = aContact;
picker.allowsAddingToAddressBook = YES;
picker.allowsActions = YES;
picker.alternateName = @"John Appleseed";
picker.title = @"John Appleseed";
picker.message = @"Company, Inc";
//创建新视图
[self.navigationController pushViewController:picker animated:YES];
}
else //添加失败,给提示信息
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error"
message:@"Could not create unknown user"
delegate:nil
cancelButtonTitle:@"Cancel"
otherButtonTitles:nil];
[alert show];
}
}
CFRelease(email);//释放
CFRelease(aContact);//释放
}
#pragma mark ABPeoplePickerNavigationControllerDelegate methods
// Displays the information of a selected person
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker
shouldContinueAfterSelectingPerson:(ABRecordRef)person
{
self.label.text = [IIAddressBook getFullName:person];
//[self dismissModalViewControllerAnimated:YES];
//return NO;
return YES;
}
// Does not allow users to perform default actions such as dialing a phone number, when they select a person property.
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person
property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier
{
return NO;
}
// Dismisses the people picker and shows the application when users tap Cancel.
- (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker;
{
[self dismissModalViewControllerAnimated:YES];
}
#pragma mark ABPersonViewControllerDelegate methods
// Does not allow users to perform default actions such as dialing a phone number, when they select a contact property.
- (BOOL)personViewController:(ABPersonViewController *)personViewController shouldPerformDefaultActionForPerson:(ABRecordRef)person
property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifierForValue
{
return NO;
}
#pragma mark ABNewPersonViewControllerDelegate methods
// Dismisses the new-person view controller.
- (void)newPersonViewController:(ABNewPersonViewController *)newPersonViewController didCompleteWithNewPerson:(ABRecordRef)person
{
[self dismissModalViewControllerAnimated:YES];
}
#pragma mark ABUnknownPersonViewControllerDelegate methods
// Dismisses the picker when users are done creating a contact or adding the displayed person properties to an existing contact.
- (void)unknownPersonViewController:(ABUnknownPersonViewController *)unknownPersonView didResolveToPerson:(ABRecordRef)person
{
[self dismissModalViewControllerAnimated:YES];
}
// Does not allow users to perform default actions such as emailing a contact, when they select a contact property.
- (BOOL)unknownPersonViewController:(ABUnknownPersonViewController *)personViewController shouldPerformDefaultActionForPerson:(ABRecordRef)person
property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier
{
return NO;
}
// 跳转至教学页面
- (void)code
{
//初始化code一些提示数据 视图
CodeViewController *controller = [[CodeViewController alloc] initWithNibName:@"CodeViewController" bundle:nil];
NSString *name = [NSString stringWithUTF8String:object_getClassName(self)];
controller.className = name;
//精简版 controller.className = [NSString stringWithUTF8String:object_getClassName(self)];
[self.navigationController pushViewController:controller animated:YES];
}
@end