在这个教程中,妳会构建一个简单的应用程序,它会提示用户从他/她的联系人列表中选择一个人,然后显示那个人的名字和电话号码。
1.在Xcode中,创建一个使用Single View Application 模板的新项目。
2.将Address Book UI和Address Book框架链接至妳的项目。
重要:如果妳不把这两个框架都链接进去的话,项目会编译失败(报告一个链接器错误)。
在创建用户界面时,可以利用Xcode的功能来声明必要的动作(actions)和属性(properties),以便于生成头文件中的大部分代码。
1.打开主故事板文件(MainStoryboard.storyboard)。
2.从库(library)面板中拖入一个按钮和两个标签(labels)到视图中,以添加它们。按照图1-1中的样子来设置它们的位置。
3.打开辅助编辑器(assistant editor)。
4.将按钮连接到视图控制器中一个名为showPicker:的新的动作方法。
这个动作,会:设置故事板中的按钮的目标和动作;向头文件中添加该方法的一个声明;在实现文件中为该方法添加一个默认的实现。妳将在稍后向默认实现代码中加入真正的代码。
5.将两个标签连接到视图控制器的两个新属性上,分别叫做firstName 和phoneNumber。
这个动作,会:在故事板中创建一个连接;在头文件中添加对应属性的声明;在实现文件中为对应的属性添加一行@synthesize。
图1-1 对用户界面进行布局
到了这个时候,ViewController.h,即该视图控制器的头文件,已经差不多完成了。在@interface那一行的末尾,加入以下代码,以声明此视图控制器类会接受ABPeoplePickerNavigationControllerDelegate 这个协议:
<ABPeoplePickerNavigationControllerDelegate>
清单1-1 中是一份完整的头文件代码。
#import <UIKit/UIKit.h> |
#import <AddressBookUI/AddressBookUI.h> |
|
@interface ViewController : UIViewController <ABPeoplePickerNavigationControllerDelegate> |
|
@property (weak, nonatomic) IBOutlet UILabel *firstName; |
@property (weak, nonatomic) IBOutlet UILabel *phoneNumber; |
|
- (IBAction)showPicker:(id)sender; |
|
@end |
在ViewController.m,即该视图控制器的实现文件中,Xcode已经为showPicker:方法创建了一份默认实现代码。清单1-2中展示的是我们真正要用到的完整代码:创建一个新的联系人选择器,将此视图控制器设置为它的代表,再将该选择器作为一个模态视图控制器来显示。
- (IBAction)showPicker:(id)sender |
{ |
ABPeoplePickerNavigationController *picker = |
[[ABPeoplePickerNavigationController alloc] init]; |
picker.peoplePickerDelegate = self; |
|
[self presentModalViewController:picker animated:YES]; |
} |
联系人选择器会根据用户的操作来调用它的代表对象的相应方法。清单1-3中展示了这些方法的实现。如果用户取消了选择器,则第一个方法会被调用,以关掉联系人选择器。如果用户选择了某个联系人,则会调用第二个方法,它会将被选中的联系人的名字和电话号码显示在界面上的标签里,并且关掉联系人选择器。
如果用户在选择器中点击了被选中的联系人的某个属性的话,则会调用第三个方法。在这个程序中,当用户选中某个联系人的时候,联系人选择器就会马上关掉,所以用户是无法再点击被选中的联系人的某个属性的。这就意味着,该方法从不会被调用。然而,如果省掉这个方法的话,对这个协议的实现就不完整了。
- (void)peoplePickerNavigationControllerDidCancel: |
(ABPeoplePickerNavigationController *)peoplePicker |
{ |
[self dismissModalViewControllerAnimated:YES]; |
} |
|
|
- (BOOL)peoplePickerNavigationController: |
(ABPeoplePickerNavigationController *)peoplePicker |
shouldContinueAfterSelectingPerson:(ABRecordRef)person { |
|
[self displayPerson:person]; |
[self dismissModalViewControllerAnimated:YES]; |
|
return NO; |
} |
|
- (BOOL)peoplePickerNavigationController: |
(ABPeoplePickerNavigationController *)peoplePicker |
shouldContinueAfterSelectingPerson:(ABRecordRef)person |
property:(ABPropertyID)property |
identifier:(ABMultiValueIdentifier)identifier |
{ |
return NO; |
} |
需要实现的最后一个方法已经在清单1-4中列出了,它会显示出联系人的名字和电话号码。注意,用于获取名字和电话号码的代码是不同的。名字是一个字符串属性——联系人记录中只有一个名字属性,并且可以是空值(NULL)。电话号码是一个多值属性——联系人记录中可以有0个、1个或多个电话号码。在这个示例中,我们会使用其中的第一个电话号码。
- (void)displayPerson:(ABRecordRef)person |
{ |
NSString* name = (__bridge_transfer NSString*)ABRecordCopyValue(person, |
kABPersonFirstNameProperty); |
self.firstName.text = name; |
|
NSString* phone = nil; |
ABMultiValueRef phoneNumbers = ABRecordCopyValue(person, |
kABPersonPhoneProperty); |
if (ABMultiValueGetCount(phoneNumbers) > 0) { |
phone = (__bridge_transfer NSString*) |
ABMultiValueCopyValueAtIndex(phoneNumbers, 0); |
} else { |
phone = @"[None]"; |
} |
self.phoneNumber.text = phone; |
CFRelease(phoneNumbers); |
} |
当妳运行这个程序时,首先会看到一个按钮及两个空白的文本标签。点击那个按钮就会弹出联系人选择器。当妳选中一个联系人之后,联系人选择器就会关闭,那个联系人的名字和电话号码会被显示在文本标签里。
竹
竹
HxLauncher: Launch Android applications by voice commands