iOS开发--系统通讯录的访问与添加联系人

时间:2022-09-05 22:34:41

  公司项目有访问通讯录的需求,所以开始了探索之路。从开始的一无所知,到知识的渐渐清晰。这一切要感谢广大无私分享的 “coder”,注:我是尊称的语气!

  苹果提供了访问系统通讯录的框架,以便开发者对系统通讯录进行操作。(此demo为纯代码),想要访问通讯录,需要添加AddressBookUI.framework和AddressBook.framework两个框架,添加的地点这里就不在赘述了。在控制器内部首先import两个头文件,<AddressBook/AddressBook.h> 和 <AddressBookUI/AddressBookUI.h>,如下图所示:

 //
// ZBSampleViewController.m
// ZBAddressBookDemo
//
// Created by zhangb on 16/02/04.
// Copyright (c) 2016年 mbp. All rights reserved.
// #import "ZBSampleViewController.h"
#import <AddressBook/AddressBook.h>
#import <AddressBookUI/AddressBookUI.h>

  首先为了方便演示与操作,这里就以两个按钮的操作代替具体的访问过程,当然具体操作要具体分析,这里只是记录访问通讯录,包括:1)查看联系人  2)向通讯录内添加联系人。下面是代码示例:

  ABPeoplePickerNavigationController为展示系统通讯录的控制器,并且需要遵循其代理方法。

 #define IS_iOS8 [[UIDevice currentDevice].systemVersion floatValue] >= 8.0f
#define IS_iOS6 [[UIDevice currentDevice].systemVersion floatValue] >= 6.0f @interface ZBSampleViewController ()<ABPeoplePickerNavigationControllerDelegate>{ ABPeoplePickerNavigationController *_abPeoplePickerVc; }
 - (void)viewDidLoad {
[super viewDidLoad]; //1.打开通讯录
UIButton *openAddressBook = [UIButton buttonWithType:UIButtonTypeCustom];
openAddressBook.frame = CGRectMake(, , , );
[openAddressBook setTitle:@"打开通讯录" forState:UIControlStateNormal];
openAddressBook.backgroundColor = [UIColor greenColor];
[openAddressBook setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[openAddressBook addTarget:self action:@selector(gotoAddressBook) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:openAddressBook]; //2.添加联系人
UIButton *addContacts = [UIButton buttonWithType:UIButtonTypeCustom];
addContacts.frame = CGRectMake(, , , );
[addContacts setTitle:@"添加联系人" forState:UIControlStateNormal];
addContacts.backgroundColor = [UIColor greenColor];
[addContacts setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[addContacts addTarget:self action:@selector(gotoAddContacts) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:addContacts]; }

  打开系统通讯录方法为openAddressBook按钮的点击事件,请忽略按钮的样式O(∩_∩)O~;

  下面的IS_iOS8为我定义的宏,判断系统的版本(上面有代码示例)。

 /**
打开通讯录
*/
- (void)gotoAddressBook{ _abPeoplePickerVc = [[ABPeoplePickerNavigationController alloc] init];
_abPeoplePickerVc.peoplePickerDelegate = self; //下面的判断是ios8之后才需要加的,不然会自动返回app内部
if(IS_iOS8){ //predicateForSelectionOfPerson默认是true (当你点击某个联系人查看详情的时候会返回app),如果你默认为true 但是实现-peoplePickerNavigationController:didSelectPerson:property:identifier:
       代理方法也是可以的,与此同时不能实现peoplePickerNavigationController: didSelectPerson:不然还是会返回app。
//总之在ios8之后加上此句比较稳妥
_abPeoplePickerVc.predicateForSelectionOfPerson = [NSPredicate predicateWithValue:false]; //predicateForSelectionOfProperty默认是true (当你点击某个联系人的某个属性的时候会返回app),此方法只要是默认值,无论你代理方法实现与否都会返回app。
// _abPeoplePickerVc.predicateForSelectionOfProperty = [NSPredicate predicateWithValue:false]; //predicateForEnablingPerson默认是true,当设置为false时,所有的联系人都不能被点击。
// _abPeoplePickerVc.predicateForEnablingPerson = [NSPredicate predicateWithValue:true];
}
[self presentViewController:_abPeoplePickerVc animated:YES completion:nil]; }

  这里需要注意的是:

  在iOS8之后需要加_abPeoplePickerVc.predicateForSelectionOfPerson = [NSPredicate predicateWithValue:false];这句代码,不然当你选择通讯录中的某个联系人的时候会直接返回app内部(类似crash)。predicateForSelectionOfPerson默认是true (当你点击某个联系人查看详情的时候会返回app),如果你默认为true 但是实现-peoplePickerNavigationController:didSelectPerson:property:identifier: 代理方法也是可以的,与此同时不能实现peoplePickerNavigationController: didSelectPerson:不然还是会返回app。

  _abPeoplePickerVc.predicateForSelectionOfProperty = [NSPredicate predicateWithValue:false];作用同上。但是_abPeoplePickerVc.predicateForEnablingPerson 的断言语句必须为true,否则任何联系人你都不能选择。上面的代码中也有详细描述。

 #pragma mark - ABPeoplePickerNavigationController的代理方法

 - (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier {

     ABMultiValueRef phone = ABRecordCopyValue(person, kABPersonPhoneProperty);

     long index = ABMultiValueGetIndexForIdentifier(phone,identifier);

     NSString *phoneNO = (__bridge NSString *)ABMultiValueCopyValueAtIndex(phone, index);
[phoneNO stringByReplacingOccurrencesOfString:@"-" withString:@""];
if (phone && phoneNO.length == ) {
//TODO:获取电话号码要做的事情 [peoplePicker dismissViewControllerAnimated:YES completion:nil];
return;
}else{
if (IS_iOS8){
UIAlertController *tipVc = [UIAlertController alertControllerWithTitle:nil message:@"请选择正确手机号" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancleAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
[self dismissViewControllerAnimated:YES completion:nil];
}];
[tipVc addAction:cancleAction];
[self presentViewController:tipVc animated:YES completion:nil]; }else{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:@"请选择正确手机号" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil];
[alertView show];
}
//非ARC模式需要释放对象
// [alertView release];
}
} - (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController*)peoplePicker didSelectPerson:(ABRecordRef)person NS_AVAILABLE_IOS(8_0)
{
ABPersonViewController *personViewController = [[ABPersonViewController alloc] init];
personViewController.displayedPerson = person; [peoplePicker pushViewController:personViewController animated:YES];
//非ARC模式需要释放对象
// [personViewController release];
} /**
peoplePickerNavigationController点击取消按钮时调用
*/
- (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker
{
[peoplePicker dismissViewControllerAnimated:YES completion:nil];
} /**
iOS8被废弃了,iOS8前查看联系人必须实现(点击联系人可以继续操作)
*/
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person NS_DEPRECATED_IOS(2_0, 8_0)
{
return YES;
} /**
iOS8被废弃了,iOS8前查看联系人属性必须实现(点击联系人属性可以继续操作)
*/
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier NS_DEPRECATED_IOS(2_0, 8_0)
{
ABMultiValueRef phone = ABRecordCopyValue(person, kABPersonPhoneProperty); long index = ABMultiValueGetIndexForIdentifier(phone,identifier); NSString *phoneNO = (__bridge NSString *)ABMultiValueCopyValueAtIndex(phone, index);
phoneNO = [phoneNO stringByReplacingOccurrencesOfString:@"-" withString:@""];
NSLog(@"%@", phoneNO);
if (phone && phoneNO.length == ) {
//TODO:获取电话号码要做的事情 [peoplePicker dismissViewControllerAnimated:YES completion:nil];
return NO;
}else{
if (IS_iOS8){
UIAlertController *tipVc = [UIAlertController alertControllerWithTitle:nil message:@"请选择正确手机号" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancleAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
[self dismissViewControllerAnimated:YES completion:nil];
}];
[tipVc addAction:cancleAction];
[self presentViewController:tipVc animated:YES completion:nil]; }else{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:@"请选择正确手机号" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil];
[alertView show];
}
}
return YES;
}

  ABPeoplePickerNavigationController的代理方法也很好理解,看字面意思就能够猜出代理方法的执行时间与能够做什么。拿第一个代理方法说明一下,也就是- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier;第一个参数就不用说了,第二个参数 ABRecordRef 这是一个联系人的引用也可以说是一个记录,你可以理解为一个联系人。第三个参数是联系人附带属性的ID,其实ABPropertyID是个int类型值。第四个参数是多值属性的标签。

  ABRecordCopyValue(ABRecordRef record, ABPropertyID property)返回一个CFTypeRef类型。此方法是从系统的通讯录内,copy出用户所选择的某个联系人数据。返回类型要看参数传递的是什么,第一个参数是联系人记录,第二个参数是参数ID,也就是用户选择的联系人的某个属性的ID。kABPersonPhoneProperty代表的是手机号码属性的ID,假如上面的ABRecordCopyValue的第二个参数传递kABPersonAddressProperty,则返回的是联系人的地址属性。下面是效果图(因为是模拟器和真机有些差异)。

iOS开发--系统通讯录的访问与添加联系人

  下面介绍下,向系统通讯录内添加联系人。这里我只设置了联系人的三个属性:名字,电话,邮件,并将属性存在了字典里。

 -(instancetype)init{
if (self = [super init]) {
_infoDictionary = [NSMutableDictionary dictionaryWithCapacity:];
[_infoDictionary setObject:@"张三" forKey:@"name"];
[_infoDictionary setObject:@"" forKey:@"phone"];
[_infoDictionary setObject:@"1000000000@qq.com" forKey:@"email"];
}
return self;
}

  因为苹果越来越注重保护用户的隐私,现在需要修改系统通讯录内的联系人信息时,必须要用户授权才可以进行。授权鉴定代码为ABAddressBookRequestAccessWithCompletion(ABAddressBookRef addressBook,  ABAddressBookRequestAccessCompletionHandler completion) __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_6_0);下面的代码中都有详细描述。

 /**
添加联系人
*/
- (void)gotoAddContacts{ //添加到通讯录,判断通讯录是否存在
if ([self isExistContactPerson]) {//存在,返回
//提示
if (IS_iOS8) {
UIAlertController *tipVc = [UIAlertController alertControllerWithTitle:@"提示" message:@"联系人已存在..." preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancleAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
[self dismissViewControllerAnimated:YES completion:nil];
}];
[tipVc addAction:cancleAction];
[self presentViewController:tipVc animated:YES completion:nil];
}else{
UIAlertView *tip = [[UIAlertView alloc] initWithTitle:@"提示" message:@"联系人已存在..." delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
[tip show];
// [tip release];
}
return;
}else{//不存在 添加
[self creatNewRecord];
}
} - (BOOL)isExistContactPerson{
//这个变量用于记录授权是否成功,即用户是否允许我们访问通讯录
int __block tip=; BOOL __block isExist = NO;
//声明一个通讯簿的引用
ABAddressBookRef addBook =nil;
//因为在IOS6.0之后和之前的权限申请方式有所差别,这里做个判断
if (IS_iOS6) {
//创建通讯簿的引用,第一个参数暂时写NULL,官方文档就是这么说的,后续会有用,第二个参数是error参数
CFErrorRef error = NULL;
addBook=ABAddressBookCreateWithOptions(NULL, &error);
//创建一个初始信号量为0的信号
dispatch_semaphore_t sema=dispatch_semaphore_create();
//申请访问权限
ABAddressBookRequestAccessWithCompletion(addBook, ^(bool greanted, CFErrorRef error) {
//greanted为YES是表示用户允许,否则为不允许
if (!greanted) {
tip=; }else{
//获取所有联系人的数组
CFArrayRef allLinkPeople = ABAddressBookCopyArrayOfAllPeople(addBook);
//获取联系人总数
CFIndex number = ABAddressBookGetPersonCount(addBook);
//进行遍历
for (NSInteger i=; i<number; i++) {
//获取联系人对象的引用
ABRecordRef people = CFArrayGetValueAtIndex(allLinkPeople, i);
//获取当前联系人名字
NSString*firstName=(__bridge NSString *)(ABRecordCopyValue(people, kABPersonFirstNameProperty)); if ([firstName isEqualToString:[_infoDictionary objectForKey:@"name"]]) {
isExist = YES;
} // //获取当前联系人姓氏
// NSString*lastName=(__bridge NSString *)(ABRecordCopyValue(people, kABPersonLastNameProperty)); //获取当前联系人中间名
// NSString*middleName=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonMiddleNameProperty));
// //获取当前联系人的名字前缀
// NSString*prefix=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonPrefixProperty));
// //获取当前联系人的名字后缀
// NSString*suffix=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonSuffixProperty));
// //获取当前联系人的昵称
// NSString*nickName=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonNicknameProperty));
// //获取当前联系人的名字拼音
// NSString*firstNamePhoneic=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonFirstNamePhoneticProperty));
// //获取当前联系人的姓氏拼音
// NSString*lastNamePhoneic=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonLastNamePhoneticProperty));
// //获取当前联系人的中间名拼音
// NSString*middleNamePhoneic=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonMiddleNamePhoneticProperty));
// //获取当前联系人的公司
// NSString*organization=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonOrganizationProperty));
// //获取当前联系人的职位
// NSString*job=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonJobTitleProperty));
// //获取当前联系人的部门
// NSString*department=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonDepartmentProperty));
// //获取当前联系人的生日
// NSString*birthday=(__bridge NSDate*)(ABRecordCopyValue(people, kABPersonBirthdayProperty));
// NSMutableArray * emailArr = [[NSMutableArray alloc]init];
// //获取当前联系人的邮箱 注意是数组
// ABMultiValueRef emails= ABRecordCopyValue(people, kABPersonEmailProperty);
// for (NSInteger j=0; j<ABMultiValueGetCount(emails); j++) {
// [emailArr addObject:(__bridge NSString *)(ABMultiValueCopyValueAtIndex(emails, j))];
// }
// //获取当前联系人的备注
// NSString*notes=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonNoteProperty));
// //获取当前联系人的电话 数组
// NSMutableArray * phoneArr = [[NSMutableArray alloc]init];
// ABMultiValueRef phones= ABRecordCopyValue(people, kABPersonPhoneProperty);
// for (NSInteger j=0; j<ABMultiValueGetCount(phones); j++) {
// [phoneArr addObject:(__bridge NSString *)(ABMultiValueCopyValueAtIndex(phones, j))];
// }
// //获取创建当前联系人的时间 注意是NSDate
// NSDate*creatTime=(__bridge NSDate*)(ABRecordCopyValue(people, kABPersonCreationDateProperty));
// //获取最近修改当前联系人的时间
// NSDate*alterTime=(__bridge NSDate*)(ABRecordCopyValue(people, kABPersonModificationDateProperty));
// //获取地址
// ABMultiValueRef address = ABRecordCopyValue(people, kABPersonAddressProperty);
// for (int j=0; j<ABMultiValueGetCount(address); j++) {
// //地址类型
// NSString * type = (__bridge NSString *)(ABMultiValueCopyLabelAtIndex(address, j));
// NSDictionary * temDic = (__bridge NSDictionary *)(ABMultiValueCopyValueAtIndex(address, j));
// //地址字符串,可以按需求格式化
// NSString * adress = [NSString stringWithFormat:@"国家:%@\n省:%@\n市:%@\n街道:%@\n邮编:%@",[temDic valueForKey:(NSString*)kABPersonAddressCountryKey],[temDic valueForKey:(NSString*)kABPersonAddressStateKey],[temDic valueForKey:(NSString*)kABPersonAddressCityKey],[temDic valueForKey:(NSString*)kABPersonAddressStreetKey],[temDic valueForKey:(NSString*)kABPersonAddressZIPKey]];
// }
// //获取当前联系人头像图片
// NSData*userImage=(__bridge NSData*)(ABPersonCopyImageData(people));
// //获取当前联系人纪念日
// NSMutableArray * dateArr = [[NSMutableArray alloc]init];
// ABMultiValueRef dates= ABRecordCopyValue(people, kABPersonDateProperty);
// for (NSInteger j=0; j<ABMultiValueGetCount(dates); j++) {
// //获取纪念日日期
// NSDate * data =(__bridge NSDate*)(ABMultiValueCopyValueAtIndex(dates, j));
// //获取纪念日名称
// NSString * str =(__bridge NSString*)(ABMultiValueCopyLabelAtIndex(dates, j));
// NSDictionary * temDic = [NSDictionary dictionaryWithObject:data forKey:str];
// [dateArr addObject:temDic];
// }
} }
//发送一次信号
dispatch_semaphore_signal(sema);
});
//等待信号触发
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
}else{ //IOS6之前
addBook =ABAddressBookCreate(); //获取所有联系人的数组
CFArrayRef allLinkPeople = ABAddressBookCopyArrayOfAllPeople(addBook);
//获取联系人总数
CFIndex number = ABAddressBookGetPersonCount(addBook);
//进行遍历
for (NSInteger i=; i<number; i++) {
//获取联系人对象的引用
ABRecordRef people = CFArrayGetValueAtIndex(allLinkPeople, i);
//获取当前联系人名字
NSString*firstName=(__bridge NSString *)(ABRecordCopyValue(people, kABPersonFirstNameProperty)); if ([firstName isEqualToString:[_infoDictionary objectForKey:@"name"]]) {
isExist = YES;
}
}
} if (tip) {
//设置提示
if (IS_iOS8) {
UIAlertController *tipVc = [UIAlertController alertControllerWithTitle:@"友情提示" message:@"请您设置允许APP访问您的通讯录\nSettings>General>Privacy" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancleAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
[self dismissViewControllerAnimated:YES completion:nil];
}];
[tipVc addAction:cancleAction];
[tipVc presentViewController:tipVc animated:YES completion:nil];
}else{
UIAlertView * alart = [[UIAlertView alloc]initWithTitle:@"友情提示" message:@"请您设置允许APP访问您的通讯录\nSettings>General>Privacy" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
[alart show];
//非ARC
// [alart release];
}
}
return isExist;
} //创建新的联系人
- (void)creatNewRecord
{
CFErrorRef error = NULL; //创建一个通讯录操作对象
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error); //创建一条新的联系人纪录
ABRecordRef newRecord = ABPersonCreate(); //为新联系人记录添加属性值
ABRecordSetValue(newRecord, kABPersonFirstNameProperty, (__bridge CFTypeRef)[_infoDictionary objectForKey:@"name"], &error); //创建一个多值属性(电话)
ABMutableMultiValueRef multi = ABMultiValueCreateMutable(kABMultiStringPropertyType);
ABMultiValueAddValueAndLabel(multi, (__bridge CFTypeRef)[_infoDictionary objectForKey:@"phone"], kABPersonPhoneMobileLabel, NULL);
ABRecordSetValue(newRecord, kABPersonPhoneProperty, multi, &error); //添加email
ABMutableMultiValueRef multiEmail = ABMultiValueCreateMutable(kABMultiStringPropertyType);
ABMultiValueAddValueAndLabel(multiEmail, (__bridge CFTypeRef)([_infoDictionary objectForKey:@"email"]), kABWorkLabel, NULL);
ABRecordSetValue(newRecord, kABPersonEmailProperty, multiEmail, &error); //添加记录到通讯录操作对象
ABAddressBookAddRecord(addressBook, newRecord, &error); //保存通讯录操作对象
ABAddressBookSave(addressBook, &error); //通过此接口访问系统通讯录
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) { if (granted) {
//显示提示
if (IS_iOS8) {
UIAlertController *alertVc = [UIAlertController alertControllerWithTitle:@"添加成功" message:nil preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *alertAction = [UIAlertAction actionWithTitle:@"知道了" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
[self dismissViewControllerAnimated:YES completion:nil]; }];
[alertVc addAction:alertAction];
[self presentViewController:alertVc animated:YES completion:nil];
}else{ UIAlertView *tipView = [[UIAlertView alloc] initWithTitle:nil message:@"添加成功" delegate:self cancelButtonTitle:@"知道了" otherButtonTitles:nil, nil];
[tipView show];
//非ARC
// [tipView release];
}
}
}); CFRelease(multiEmail);
CFRelease(multi);
CFRelease(newRecord);
CFRelease(addressBook);
}

  代码中有每个步骤都有对应的注释,对应看起来会容易一些!下面是效果图:

iOS开发--系统通讯录的访问与添加联系人

  如果需要添加联系人的其他属性,方法类似,只是属性名不同。慢慢挖掘吧,伙伴们!

  声明:此文仅为了记录本人开发中的遇到并解决的问题,权当是一篇笔记,并不是教学blog,不免会有错误,如有烦请指正,大家共同学习!谢谢!

  下面列举一些参考blog:(再次感谢无私分享的coder)

  http://m.open-open.com/m/code/view/1432302834146

  http://supershll.blog.163.com/blog/static/37070436201272821810474/

  http://www.tuicool.com/articles/Mvuu6z

iOS开发--系统通讯录的访问与添加联系人的更多相关文章

  1. iOS开发UI篇—在UIImageView中添加按钮以及Tag的参数说明

    ios开发UI篇—在ImageView中添加按钮以及Tag的参数说明 一.tag参数 一个视图通常都只有一个父视图,多个子视图,在开发中可以通过使用子视图的tag来取出对应的子视图.方法为Viewwi ...

  2. ios开发UI篇—在ImageView中添加按钮以及Tag的参数说明

    ios开发UI篇—在ImageView中添加按钮以及Tag的参数说明 一.tag参数 一个视图通常都只有一个父视图,多个子视图,在开发中可以通过使用子视图的tag来取出对应的子视图.方法为Viewwi ...

  3. IOS 通讯录 (访问,添加,修改)

      如何访问用户的通讯录 在iOS中,有2个框架可以访问用户的通讯录 AddressBookUI.framework 提供了联系人列表界面.联系人详情界面.添加联系人界面等 一般用于选择联系人 Add ...

  4. iOS开发系列--通讯录、蓝牙、内购、GameCenter、iCloud、Passbook系统服务开发汇总

    --系统应用与系统服务 iOS开发过程中有时候难免会使用iOS内置的一些应用软件和服务,例如QQ通讯录.微信电话本会使用iOS的通讯录,一些第三方软件会在应用内发送短信等.今天将和大家一起学习如何使用 ...

  5. iOS开发系列通讯录、蓝牙、内购、GameCenter、iCloud、Passbook系统服务开

    --系统应用与系统服务 iOS开发过程中有时候难免会使用iOS内置的一些应用软件和服务,例如QQ通讯录.微信电话本会使用iOS的通讯录,一些第三方软件会在应用内发送短信等.今天将和大家一起学习如何使用 ...

  6. iOS开发系列--通讯录、蓝牙、

    iOS开发过程中有时候难免会使用iOS内置的一些应用软件和服务,例如QQ通讯录.微信电话本会使用iOS的通讯录,一些第三方软件会在应用内发送短信等.今天将和大家一起学习如何使用系统应用.使用系统服务: ...

  7. iOS开发时,在Xcode中添加多个Targets进行版本控制

    在iOS开发中,很可能有以下场景:需要开发多个版本,或因需区分收费版,免费版,或因为网络环境需要区分测试版,发布版,或因渠道不同需要区分企业版,AppStore版等等.解决办法无非就是CheckOut ...

  8. iOS调用系统通讯录获取姓名电话号码(转)

    原文地址:http://blog.csdn.net/idoshi201109/article/details/46007125 OS调用系统通讯录获取姓名电话号码 (iOS 8.0 Xcode6.3可 ...

  9. IOS 获取系统通讯录

    进入正题  获取系统通讯录,不想多讲,留下链接http://my.oschina.net/joanfen/blog/140146 通常做法: 首先创建一个ABAddressBookRef类的对象add ...

随机推荐

  1. &lbrack;译&rsqb;IIS 8&period;0应用初始化

    原文 代码 或者点这 通过IIS 8.0应用初始化特性管理员可以配置IIS为一个网站或多个网站提前执行初始化任务.当应用在初始化期间,可以通过配置先返回一个静态页面知道应用的初始化任务完成. 通过配置 ...

  2. 深入浅出React Native 3&colon; 从零开始写一个Hello World

    这是深入浅出React Native的第三篇文章. 1. 环境配置 2. 我的第一个应用 将index.ios.js中的代码全部删掉,为什么要删掉呢?因为我们准备从零开始写一个应用~学习技术最好的方式 ...

  3. Asp&period;net实现直接在浏览器预览Word、Excel、PDF、Txt文件(附源码)

    功能说明 输入文件路径,在浏览器输出文件预览信息,经测试极速(Chrome).IE9.Firefox通过 分类文件及代码说明  DemoFiles 存放可测试文件 Default.aspx  启动页 ...

  4. nginx相关

    定时切割nginx日志#!/bin/bash #desc: cut nginx log #this script run at 00:00 LOG_PATH='/usr/local/nginx/log ...

  5. Ubuntu13&period;04 配置smb服务器-new

    1.安装smb服务器:apt-get install samba 2.安装smb支持的文件系统:apt-get install smbfs 或者cifs-utils(因为可能会提示smbfs以过期,已 ...

  6. js获取fck值的代码方法

    引入js文件 <script type="text/javascript" src="${basePath}/FCKeditor/fckeditor.js&quot ...

  7. 轻量级Java&lowbar;EE企业应用实战-第5章Hibernate的基本用法-001

    1. package org.crazyit.app.domain; import javax.persistence.*; /** * Description: <br/> * ��վ: ...

  8. C&plus;&plus;11 &colon; variadic templates&lpar;可变参数模板&rpar;

      Introduction: Before the possibilities of the new C++ language standard, C++11, the use of templat ...

  9. 利用ant进行编译和发布项目

    本文通过一个示例来解说如何通过ant进行编译和发布项目.本例按如下目录结构来组织项目. D:/web/antsample项目根目录 D:/web/antsample/src源代码目录 D:/web/a ...

  10. windows phone 8&period;1开发&colon;文件选择器FileSavePicker

    上一篇文章小梦分享了文件选择器FileOpenPicker的用法,这篇文章我们继续分享FileSavePicker的用法,FileSavePicker的用法几乎和FileOpenPicker用法一模一 ...