按照时间排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
//排序 对时间进行排序
NSMutableArray *dataArray=[[NSMutableArray alloc]initWithCapacity:0];
NSMutableDictionary *dir=[[NSMutableDictionary alloc]init];
[dir setObject:@"2012-12-02" forKey:@"time"];
[dataArray addObject:dir];


NSMutableDictionary *dir1=[[NSMutableDictionary alloc]init];
[dir1 setObject:@"2012-02-15" forKey:@"time"];
[dataArray addObject:dir1];


NSMutableDictionary *dir2=[[NSMutableDictionary alloc]init];
[dir2 setObject:@"2012-03-02" forKey:@"time"];
[dataArray addObject:dir2];


NSMutableDictionary *dir3=[[NSMutableDictionary alloc]init];
[dir3 setObject:@"2000-03-02" forKey:@"time"];
[dataArray addObject:dir3];


NSMutableDictionary *dir4=[[NSMutableDictionary alloc]init];
[dir4 setObject:@"2112-03-02" forKey:@"time"];
[dataArray addObject:dir4];


NSMutableArray *myArray=[[NSMutableArray alloc]initWithCapacity:0];
[myArray addObjectsFromArray:dataArray];
//[myArray release];


for (int i=0; i<[myArray count]; i++) {
NSLog(@"排序前----->>%@",[[myArray objectAtIndex:i] objectForKey:@"time"]);
}

NSSortDescriptor *sorter = [[NSSortDescriptor alloc]initWithKey:@"time" ascending:YES];
NSMutableArray *sortDescriptors=[[NSMutableArray alloc]initWithObjects:&sorter count:1];
NSArray *sortArray=[myArray sortedArrayUsingDescriptors:sortDescriptors];



for (int i=0; i<[sortArray count]; i++) {
NSLog(@"排序后----->>%@",[[sortArray objectAtIndex:i] objectForKey:@"time"]);
}

模态

/模态:就是从一个页面中弹出一个临时的页面,用来收集用户信息,常用于登陆注册页面/

aViewController.m中调用bViewController.m的模态

aViewController.m/*/在 - (void)viewDidLoad
中用Button调用action方法-(void)action{ //1.用bViewController创建bViewController的对象bVC bViewController*bVC = [[bViewControlleralloc]init]; //2.用self 调用模态控制器方法 //animated:是否有动画 [selfpresentViewController:bVCanimated:YEScompletion:^{ //可以设置方法处理事件
}]; //3.设置模态样式 [bVCsetModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];

}/*/

bViewController.m /*/在 - (void)viewDidLoad
中用Button调用action方法-(void)action{
//用self 调用模态控制器方法
模态消失 [selfdismissViewControllerAnimated:YEScompletion:^{ //可以设置方法处理事件
}];}/*/

汉字转拼音

1
2
3
4
5
6
7
8
9
10
带音标
CFMutableStringRefstring = CFStringCreateMutableCopy(NULL,0,CFSTR("中国"));
CFStringTransform(string,NULL,kCFStringTransformMandarinLatin,NO);
NSLog(@"%@", string);

不带音标
CFMutableStringRefstring = CFStringCreateMutableCopy(NULL,0,CFSTR("中国"));
CFStringTransform(string,NULL,kCFStringTransformMandarinLatin,NO);
CFStringTransform(string,NULL,kCFStringTransformStripDiacritics,NO);
NSLog(@"%@", string);

数组 基本用法和排序

1.创建数组

[objc] view
plain
copy在CODE上查看代码片派生到我的代码片1. // 创建一个空的数组

  1. NSArray *array = [NSArray array];
  2. // 创建有1个元素的数组
  3. array = [NSArray arrayWithObject:@”123”];
  4. // 创建有多个元素的数组
  5. array = [NSArray arrayWithObjects:@”a”, @”b”, @”c”, nil nil];
  6. NSArray *array3 = [array arrayByAddingObjectsFromArray:[NSArray arrayWithObjects:@”4”, @”5”, nil nil]];
  7. NSArray *array4 = [NSArray arrayWithObjects:@”1”, @”2”, @”3”, @”4”, nil nil];
  8. NSRange range = NSMakeRange(1, 2);
  9. NSArray *array5 = [array4 subarrayWithRange:range];

2.数组的一些基本方法

[objc] view
plain
copy在CODE上查看代码片派生到我的代码片1. int count = [array count];//个数

  1. // 判断是否包含了某个元素
  2. if ([array containsObject:@”a”]) {
  3. NSLog(@”包含了字符串a”);
  4. }
  5. NSString *last = [array lastObject];最后一个元素
  6. NSString *str = [array objectAtIndex:1];根据索引获取数组中的元素
  7. int index = [array indexOfObject:@”c”];获取指定元素的索引
  8. // 让数组里面的所有对象都调用test方法,123为参数
  9. NSArray *array = [NSArray arrayWithObjects:stu1, stu2, stu3, nil nil];
  10. [array makeObjectsPerformSelector:@selector(test2:) withObject:@”123”];
  11. NSArray *array = [NSArray arrayWithObjects:@”1”, @”2”, @”3”, @”4”, nil nil];
  12. // 1-2-3-4
  13. // 利用分隔符-拼接所有的数组元素
  14. NSString *str = [array componentsJoinedByString:@”-“];
  15. // 将一个数组写入文件(生成的是一个xml文件)
  16. NSString *path = @”/Users/apple/Desktop/array.xml”;
  17. [array writeToFile:path atomically:YES];
  18. path = @”/Users/apple/Desktop/array.txt”;
  19. // 从文件中读取数组内容(文件有严格的格式要求)
  20. NSArray *array2 = [NSArray arrayWithContentsOfFile:path];

3.遍历数组

[objc] view
plain
copy在CODE上查看代码片派生到我的代码片1. #pragma mark 遍历数组1

  1. void arrayFor1() {
  2. NSArray *array = [NSArray arrayWithObjects:stu1, @”1”, @”2”, @”3”, nil nil];
  3. int count = array.count;
  4. for (int i = 0; i<count; i++) {
  5. id obj = [array objectAtIndex:i];
  6. }
  7. }
  8. #pragma mark 遍历数组2 快速遍历
  9. void arrayFor2() {
  10. Student *stu1 = [Student student];
  11. NSArray *array = [NSArray arrayWithObjects:stu1, @”1”, @”2”, @”3”, nil nil];
  12. int i =0;
  13. for (id obj in array) {
  14. NSLog(@”%i-%@”, i, obj);
  15. i++;
  16. }
  17. }
  18. #pragma mark 遍历数组3
  19. void arrayFor3() {
  20. Student *stu1 = [Student student];
  21. NSArray *array = [NSArray arrayWithObjects:stu1, @”1”, @”2”, @”3”, nil nil];
  22. [array enumerateObjectsUsingBlock:
  23. ^(id obj, NSUInteger idx, BOOLBOOL *stop) {
  24. NSLog(@”%i-%@”, idx, obj);
  25. // 如果索引为1,就停止遍历
  26. if (idx == 1) {
  27. // 利用指针修改外面BOOL变量的值
  28. *stop = YES;
  29. }
  30. }];
  31. }
  32. #pragma mark 遍历数组4
  33. void arrayFor4() {
  34. Student *stu1 = [Student student];
  35. NSArray *array = [NSArray arrayWithObjects:stu1, @”1”, @”2”, @”3”, nil nil];
  36. // 获取数组的迭代器
  37. // NSEnumerator *enumerator = [array objectEnumerator];
  38. // 反序迭代器(从尾部开始遍历元素)
  39. NSEnumerator *enumerator = [array reverseObjectEnumerator];
  40. // allObjects是取出没有被遍历过的对象
  41. NSArray *array2 = [enumerator allObjects];
  42. NSLog(@”array2:%@”, array2);
  43. // 获取下一个需要遍历的元素
  44. id obj = nil;
  45. while (obj = [enumerator nextObject]) {
  46. NSLog(@”obj=%@”, obj);
  47. }
  48. }

4.数组排序

[objc] view
plain
copy在CODE上查看代码片派生到我的代码片1. #pragma mark 数组排序1

  1. void arraySort1() {
  2. NSArray *array = [NSArray arrayWithObjects:@”2”, @”3”, @”1”, @”4”, nil nil];
  3. // 返回一个排好序的数组,原来数组的元素顺序不会改变
  4. // 指定元素的比较方法:compare:
  5. NSArray *array2 = [array sortedArrayUsingSelector:@selector(compare:)];
  6. NSLog(@”array2:%@”, array2);
  7. }
  8. #pragma mark 数组排序2
  9. void arraySort2() {
  10. Student *stu1 = [Student studentWithFirstname:@”MingJie” lastname:@”Li”];
  11. Student *stu2 = [Student studentWithFirstname:@”LongHu” lastname:@”Huang”];
  12. Student *stu3 = [Student studentWithFirstname:@”LianJie” lastname:@”Li”];
  13. Student *stu4 = [Student studentWithFirstname:@”Jian” lastname:@”Xiao”];
  14. NSArray *array = [NSArray arrayWithObjects:stu1,stu2,stu3, stu4, nil nil];
  15. // 指定排序的比较方法
  16. NSArray *array2 = [array sortedArrayUsingSelector:@selector(compareStudent:)];
  17. NSLog(@”array2:%@”, array2);
  18. }
    • (NSComparisonResult)compareStudent:(Student *)stu {
  19. // 先按照姓排序
  20. NSComparisonResult result = [self.lastname compare:stu.lastname];
  21. // 如果有相同的姓,就比较名字
  22. if (result == NSOrderedSame) {
  23. result = [self.firstname compare:stu.firstname];
  24. }
  25. return result;
  26. }
  27. #pragma mark 数组排序3
  28. void arraySort3() {
  29. Student *stu1 = [Student studentWithFirstname:@”MingJie” lastname:@”Li”];
  30. Student *stu2 = [Student studentWithFirstname:@”LongHu” lastname:@”Huang”];
  31. Student *stu3 = [Student studentWithFirstname:@”LianJie” lastname:@”Li”];
  32. Student *stu4 = [Student studentWithFirstname:@”Jian” lastname:@”Xiao”];
  33. NSArray *array = [NSArray arrayWithObjects:stu1,stu2,stu3, stu4, nil nil];
  34. // 利用block进行排序
  35. NSArray *array2 = [array sortedArrayUsingComparator:
  36. ^NSComparisonResult(Student obj1, Student obj2) {
  37. // 先按照姓排序
  38. NSComparisonResult result = [obj1.lastname compare:obj2.lastname];
  39. // 如果有相同的姓,就比较名字
  40. if (result == NSOrderedSame) {
  41. result = [obj1.firstname compare:obj2.firstname];
  42. }
  43. return result;
  44. }];
  45. NSLog(@”array2:%@”, array2);
  46. }
  47. #pragma mark 数组排序4-高级排序
  48. void arraySort4() {
  49. Student *stu1 = [Student studentWithFirstname:@”MingJie” lastname:@”Li” bookName:@”book1”];
  50. Student *stu2 = [Student studentWithFirstname:@”LongHu” lastname:@”Huang” bookName:@”book2”];
  51. Student *stu3 = [Student studentWithFirstname:@”LianJie” lastname:@”Li” bookName:@”book2”];
  52. Student *stu4 = [Student studentWithFirstname:@”Jian” lastname:@”Xiao” bookName:@”book1”];
  53. NSArray *array = [NSArray arrayWithObjects:stu1,stu2,stu3, stu4, nil nil];
  54. // 1.先按照书名进行排序
  55. // 这里的key写的是@property的名称
  56. NSSortDescriptor *bookNameDesc = [NSSortDescriptor sortDescriptorWithKey:@”book.name” ascending:YES];
  57. // 2.再按照姓进行排序
  58. NSSortDescriptor *lastnameDesc = [NSSortDescriptor sortDescriptorWithKey:@”lastname” ascending:YES];
  59. // 3.再按照名进行排序
  60. NSSortDescriptor *firstnameDesc = [NSSortDescriptor sortDescriptorWithKey:@”firstname” ascending:YES];
  61. // 按顺序添加排序描述器
  62. NSArray *descs = [NSArray arrayWithObjects:bookNameDesc, lastnameDesc, firstnameDesc, nil nil];
  63. NSArray *array2 = [array sortedArrayUsingDescriptors:descs];
  64. NSLog(@”array2:%@”, array2);
  65. }

获取当前时间

1
2
3
4
5
6
7
//获取当前时间
NSDate *date = [NSDate date];
//时间格式
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
dateFormatter.dateFormat = @"YYYY-MM-dd HH:mm:ss";
//时间转换
NSString *time = [dateFormatter stringFromDate:date];

计算字符串的宽或者高

`objc
/* 返回值是该字符串所占的大小(width,
height)
font :该字符串所用的字体(字体大小不一样,显示出来的面积也不同) maxSize :为限制改字体的最大宽和高(如果显示一行,则宽高都设置为MAXFLOAT,如果显示为多行,只需将宽设置一个有限定长值,高设置为MAXFLOAT)
/+(CGSize)sizeWithFont:(UIFont )font maxSize:(CGSize)maxSize
content:(NSString )content;
//返回字符串所占用的尺寸.
+(CGSize)sizeWithFont:(UIFont
)font maxSize:(CGSize)maxSize content:(NSString)content
{
NSDictionary
attrs =@{NSFontAttributeName: font};

return[contentboundingRectWithSize:maxSizeoptions:NSStringDrawingUsesLineFragmentOriginattributes:attrscontext:nil].size;}

通知

#warning通知第一步,注册通知
// NSNotification消息通知类,是抽象类,使用他的子类,消息中心单例 [[NSNotificationCenterdefaultCenter] addObserver:selfselector:@selector(changeColor:)name:@”changeColor”object:nil]; #warning通知第二步,实现通知触发的方法
//当收到通知后,该方法会被执行
-(void)changeColor:(NSNotification*)notification
{

#warning通知第四步,接收消息
UIColorcolor = (UIColor)[notificationobject];
self.view.backgroundColor= color;}

#warning通知第三步,发送通知
[[NSNotificationCenterdefaultCenter]postNotificationName:@”changeColor”object:[UIColorredColor]]; [[NSNotificationCenterdefaultCenter]postNotificationName:@”changeColor2”object:[UIColorredColor]];

  • (void)dealloc
    {
    [[NSNotificationCenterdefaultCenter]removeObserver:selfname:@”changeColor”object:nil];
    [superdealloc];}

让超出自己视图范围的子视图响应事件

有时需要让子视图的位置超出父视图,这时子视图不会响应点击事件,在父视图中实现这个方法,可以让子视图超出的部分也响应点击事件
父视图需要是view的子类
这个方法可以判断出自己的子视图,和子视图的子视图,在多层的话需要继续遍历

通讯录

通讯录
AddressBook
iOS中带有一个Contacts应用程序来管理联系人,但是有些时候我们希望自己的应用能够访问或者修改这些信息,这个时候就要用到AddressBook.framework框架。iOS中的通讯录是存储在数据库中的,由于iOS的权限设计,开发人员是不允许直接访问通讯录数据库的,必须依靠AddressBook提供的标准API来实现通讯录操作。通过AddressBook.framework开发者可以从底层去操作AddressBook.framework的所有信息,但是需要注意的是这个框架是基于C语言编写的,无法使用ARC来管理内存,开发者需要自己管理内存。下面大致介绍一下通讯录操作中常用的类型:
ABAddressBookRef:代表通讯录对象,通过该对象开发人员不用过多的关注通讯录的存储方式,可以直接以透明的方式去访问、保存(在使用AddressBook.framework操作联系人时,所有的增加、删除、修改后都必须执行保存操作,类似于Core Data)等。
ABRecordRef:代表一个通用的记录对象,可以是一条联系人信息,也可以是一个群组,可以通过ABRecordGetRecordType()函数获得具体类型。如果作为联系人(事实上也经常使用它作为联系人),那么这个记录记录了一个完整的联系人信息(姓名、性别、电话、邮件等),每条记录都有一个唯一的ID标示这条记录(可以通过ABRecordGetRecordID()函数获得)。
ABPersonRef:代表联系人信息,很少直接使用,实际开发过程中通常会使用类型为“kABPersonType”的ABRecordRef来表示联系人(由此可见ABPersonRef其实是一种类型为“kABPersonType”的ABRecordRef)
ABGroupRef:代表群组,与ABPersonRef类似,很少直接使用ABGroupRef,而是使用类型为“kABGroupType”的ABRecordRef来表示群组,一个群组可以包含多个联系人,一个联系人也同样可以多个群组。
由于通讯录操作的关键是对ABRecordRef的操作,首先看一下常用的操作通讯录记录的方法:
ABPersonCreate():创建一个类型为“kABPersonType”的ABRecordRef。
ABRecordCopyValue():取得指定属性的值。
ABRecordCopyCompositeName():取得联系人(或群组)的复合信息(对于联系人则包括:姓、名、公司等信息,对于群组则返回组名称)。
ABRecordSetValue():设置ABRecordRef的属性值。注意在设置ABRecordRef的值时又分为单值属性和多值属性:单值属性设置只要通过ABRecordSetValue()方法指定属性名和值即可;多值属性则要先通过创建一个ABMutableMultiValueRef类型的变量,然后通过ABMultiValueAddValueAndLabel()方法依次添加属性值,最后通过ABRecordSetValue()方法将ABMutableMultiValueRef类型的变量设置为记录值。
ABRecordRemoveValue():删除指定的属性值。
注意:
由于联系人访问时(读取、设置、删除时)牵扯到大量联系人属性,可以到ABPerson.h中查询或者直接到帮助文档“Personal Information Properties”
通讯录的访问步骤一般如下:
调用ABAddressBookCreateWithOptions()方法创建通讯录对象ABAddressBookRef。
调用ABAddressBookRequestAccessWithCompletion()方法获得用户授权访问通讯录。
调用ABAddressBookCopyArrayOfAllPeople()、ABAddressBookCopyPeopleWithName()方法查询联系人信息。
读取联系人后如果要显示联系人信息则可以调用ABRecord相关方法读取相应的数据;如果要进行修改联系人信息,则可以使用对应的方法修改ABRecord信息,然后调用ABAddressBookSave()方法提交修改;如果要删除联系人,则可以调用ABAddressBookRemoveRecord()方法删除,然后调用ABAddressBookSave()提交修改操作。
也就是说如果要修改或者删除都需要首先查询对应的联系人,然后修改或删除后提交更改。如果用户要增加一个联系人则不用进行查询,直接调用ABPersonCreate()方法创建一个ABRecord然后设置具体的属性,调用ABAddressBookAddRecord方法添加即可。
下面就通过一个示例演示一下如何通过ABAddressBook.framework访问通讯录,这个例子中通过一个UITableViewController模拟一下通讯录的查看、删除、添加操作。
主控制器视图,用于显示联系人,修改删除联系人:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
KCContactViewController.h
//
// KCTableViewController.h
// AddressBook
//
// Created by Kenshin Cui on 14/04/05.
// Copyright (c) 2014年 cmjstudio. All rights reserved.
//

#import <UIKit/UIKit.h>

/**
* 定义一个协议作为代理
*/
@protocol KCContactDelegate
//新增或修改联系人
-(void)editPersonWithFirstName:(NSString *)firstName lastName:(NSString *)lastName workNumber:(NSString *)workNumber;
//取消修改或新增
-(void)cancelEdit;
@end

@interface KCContactTableViewController : UITableViewController

@end
KCContactViewController.m
//
// KCTableViewController.m
// AddressBook
//
// Created by Kenshin Cui on 14/04/05.
// Copyright (c) 2014年 cmjstudio. All rights reserved.
//

#import "KCContactTableViewController.h"
#import <AddressBook/AddressBook.h>
#import "KCAddPersonViewController.h"

@interface KCContactTableViewController ()<KCContactDelegate>

@property (assign,nonatomic) ABAddressBookRef addressBook;//通讯录
@property (strong,nonatomic) NSMutableArray *allPerson;//通讯录所有人员

@property (assign,nonatomic) int isModify;//标识是修改还是新增,通过选择cell进行导航则认为是修改,否则视为新增
@property (assign,nonatomic) UITableViewCell *selectedCell;//当前选中的单元格

@end

@implementation KCContactTableViewController

#pragma mark - 控制器视图
- (void)viewDidLoad {
[super viewDidLoad];

//请求访问通讯录并初始化数据
[self requestAddressBook];
}

//由于在整个视图控制器周期内addressBook都驻留在内存中,所有当控制器视图销毁时销毁该对象
-(void)dealloc{
if (self.addressBook!=NULL) {
CFRelease(self.addressBook);
}
}

#pragma mark - UI事件
//点击删除按钮
- (IBAction)trashClick:(UIBarButtonItem *)sender {
self.tableView.editing=!self.tableView.editing;
}


#pragma mark - UITableView数据源方法

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.allPerson.count;
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *identtityKey=@"myTableViewCellIdentityKey1";
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:identtityKey];
if(cell==nil){
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:identtityKey];
}
//取得一条人员记录
ABRecordRef recordRef=(__bridge ABRecordRef)self.allPerson[indexPath.row];
//取得记录中得信息
NSString *firstName=(__bridge NSString *) ABRecordCopyValue(recordRef, kABPersonFirstNameProperty);//注意这里进行了强转,不用自己释放资源
NSString *lastName=(__bridge NSString *)ABRecordCopyValue(recordRef, kABPersonLastNameProperty);

ABMultiValueRef phoneNumbersRef= ABRecordCopyValue(recordRef, kABPersonPhoneProperty);//获取手机号,注意手机号是ABMultiValueRef类,有可能有多条
// NSArray *phoneNumbers=(__bridge NSArray *)ABMultiValueCopyArrayOfAllValues(phoneNumbersRef);//取得CFArraryRef类型的手机记录并转化为NSArrary
long count= ABMultiValueGetCount(phoneNumbersRef);
// for(int i=0;i<count;++i){
// NSString *phoneLabel= (__bridge NSString *)(ABMultiValueCopyLabelAtIndex(phoneNumbersRef, i));
// NSString *phoneNumber=(__bridge NSString *)(ABMultiValueCopyValueAtIndex(phoneNumbersRef, i));
// NSLog(@"%@:%@",phoneLabel,phoneNumber);
// }

cell.textLabel.text=[NSString stringWithFormat:@"%@ %@",firstName,lastName];
if (count>0) {
cell.detailTextLabel.text=(__bridge NSString *)(ABMultiValueCopyValueAtIndex(phoneNumbersRef, 0));
}
if(ABPersonHasImageData(recordRef)){//如果有照片数据
NSData *imageData= (__bridge NSData *)(ABPersonCopyImageData(recordRef));
cell.imageView.image=[UIImage imageWithData:imageData];
}else{
cell.imageView.image=[UIImage imageNamed:@"avatar"];//没有图片使用默认头像
}
//使用cell的tag存储记录id
cell.tag=ABRecordGetRecordID(recordRef);

return cell;
}


- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
ABRecordRef recordRef=(__bridge ABRecordRef )self.allPerson[indexPath.row];
[self removePersonWithRecord:recordRef];//从通讯录删除
[self.allPerson removeObjectAtIndex:indexPath.row];//从数组移除
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];//从列表删除
} else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}

#pragma mark - UITableView代理方法
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
self.isModify=1;
self.selectedCell=[tableView cellForRowAtIndexPath:indexPath];
[self performSegueWithIdentifier:@"AddPerson" sender:self];
}

#pragma mark - Navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if([segue.identifier isEqualToString:@"AddPerson"]){
UINavigationController *navigationController=(UINavigationController *)segue.destinationViewController;
//根据导航控制器取得添加/修改人员的控制器视图
KCAddPersonViewController *addPersonController=(KCAddPersonViewController *)navigationController.topViewController;
addPersonController.delegate=self;
//如果是通过选择cell进行的导航操作说明是修改,否则为添加
if (self.isModify) {
UITableViewCell *cell=self.selectedCell;
addPersonController.recordID=(ABRecordID)cell.tag;//设置
NSArray *array=[cell.textLabel.text componentsSeparatedByString:@" "];
if (array.count>0) {
addPersonController.firstNameText=[array firstObject];
}
if (array.count>1) {
addPersonController.lastNameText=[array lastObject];
}
addPersonController.workPhoneText=cell.detailTextLabel.text;

}
}
}


#pragma mark - KCContact代理方法
-(void)editPersonWithFirstName:(NSString *)firstName lastName:(NSString *)lastName workNumber:(NSString *)workNumber{
if (self.isModify) {
UITableViewCell *cell=self.selectedCell;
NSIndexPath *indexPath= [self.tableView indexPathForCell:cell];
[self modifyPersonWithRecordID:(ABRecordID)cell.tag firstName:firstName lastName:lastName workNumber:workNumber];
[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationRight];
}else{
[self addPersonWithFirstName:firstName lastName:lastName workNumber:workNumber];//通讯簿中添加信息
[self initAllPerson];//重新初始化数据
[self.tableView reloadData];
}
self.isModify=0;
}
-(void)cancelEdit{
self.isModify=0;
}

#pragma mark - 私有方法
/**
* 请求访问通讯录
*/
-(void)requestAddressBook{
//创建通讯录对象
self.addressBook=ABAddressBookCreateWithOptions(NULL, NULL);

//请求访问用户通讯录,注意无论成功与否block都会调用
ABAddressBookRequestAccessWithCompletion(self.addressBook, ^(bool granted, CFErrorRef error) {
if (!granted) {
NSLog(@"未获得通讯录访问权限!");
}
[self initAllPerson];

});
}
/**
* 取得所有通讯录记录
*/
-(void)initAllPerson{
//取得通讯录访问授权
ABAuthorizationStatus authorization= ABAddressBookGetAuthorizationStatus();
//如果未获得授权
if (authorization!=kABAuthorizationStatusAuthorized) {
NSLog(@"尚未获得通讯录访问授权!");
return ;
}
//取得通讯录中所有人员记录
CFArrayRef allPeople= ABAddressBookCopyArrayOfAllPeople(self.addressBook);
self.allPerson=(__bridge NSMutableArray *)allPeople;

//释放资源
CFRelease(allPeople);

}

/**
* 删除指定的记录
*
* @param recordRef 要删除的记录
*/
-(void)removePersonWithRecord:(ABRecordRef)recordRef{
ABAddressBookRemoveRecord(self.addressBook, recordRef, NULL);//删除
ABAddressBookSave(self.addressBook, NULL);//删除之后提交更改
}
/**
* 根据姓名删除记录
*/
-(void)removePersonWithName:(NSString *)personName{
CFStringRef personNameRef=(__bridge CFStringRef)(personName);
CFArrayRef recordsRef= ABAddressBookCopyPeopleWithName(self.addressBook, personNameRef);//根据人员姓名查找
CFIndex count= CFArrayGetCount(recordsRef);//取得记录数
for (CFIndex i=0; i<count; ++i) {
ABRecordRef recordRef=CFArrayGetValueAtIndex(recordsRef, i);//取得指定的记录
ABAddressBookRemoveRecord(self.addressBook, recordRef, NULL);//删除
}
ABAddressBookSave(self.addressBook, NULL);//删除之后提交更改
CFRelease(recordsRef);
}

/**
* 添加一条记录
*
* @param firstName 名
* @param lastName 姓
* @param iPhoneName iPhone手机号
*/
-(void)addPersonWithFirstName:(NSString *)firstName lastName:(NSString *)lastName workNumber:(NSString *)workNumber{
//创建一条记录
ABRecordRef recordRef= ABPersonCreate();
ABRecordSetValue(recordRef, kABPersonFirstNameProperty, (__bridge CFTypeRef)(firstName), NULL);//添加名
ABRecordSetValue(recordRef, kABPersonLastNameProperty, (__bridge CFTypeRef)(lastName), NULL);//添加姓

ABMutableMultiValueRef multiValueRef =ABMultiValueCreateMutable(kABStringPropertyType);//添加设置多值属性
ABMultiValueAddValueAndLabel(multiValueRef, (__bridge CFStringRef)(workNumber), kABWorkLabel, NULL);//添加工作电话
ABRecordSetValue(recordRef, kABPersonPhoneProperty, multiValueRef, NULL);

//添加记录
ABAddressBookAddRecord(self.addressBook, recordRef, NULL);

//保存通讯录,提交更改
ABAddressBookSave(self.addressBook, NULL);
//释放资源
CFRelease(recordRef);
CFRelease(multiValueRef);
}

/**
* 根据RecordID修改联系人信息
*
* @param recordID 记录唯一ID
* @param firstName 姓
* @param lastName 名
* @param homeNumber 工作电话
*/
-(void)modifyPersonWithRecordID:(ABRecordID)recordID firstName:(NSString *)firstName lastName:(NSString *)lastName workNumber:(NSString *)workNumber{
ABRecordRef recordRef=ABAddressBookGetPersonWithRecordID(self.addressBook,recordID);
ABRecordSetValue(recordRef, kABPersonFirstNameProperty, (__bridge CFTypeRef)(firstName), NULL);//添加名
ABRecordSetValue(recordRef, kABPersonLastNameProperty, (__bridge CFTypeRef)(lastName), NULL);//添加姓

ABMutableMultiValueRef multiValueRef =ABMultiValueCreateMutable(kABStringPropertyType);
ABMultiValueAddValueAndLabel(multiValueRef, (__bridge CFStringRef)(workNumber), kABWorkLabel, NULL);
ABRecordSetValue(recordRef, kABPersonPhoneProperty, multiValueRef, NULL);
//保存记录,提交更改
ABAddressBookSave(self.addressBook, NULL);
//释放资源
CFRelease(multiValueRef);
}
@end
新增或修改控制器视图,用于显示一个联系人的信息或者新增一个联系人:
KCAddPersonViewController.h
//
// KCAddPersonViewController.h
// AddressBook
//
// kABPersonFirstNameProperty
// Copyright (c) 2014年 cmjstudio. All rights reserved.
//

#import <UIKit/UIKit.h>
@protocol KCContactDelegate;

@interface KCAddPersonViewController : UIViewController

@property (assign,nonatomic) int recordID;//通讯录记录id,如果ID不为0则代表修改否则认为是新增
@property (strong,nonatomic) NSString *firstNameText;
@property (strong,nonatomic) NSString *lastNameText;
@property (strong,nonatomic) NSString *workPhoneText;

@property (strong,nonatomic) id<KCContactDelegate> delegate;

@end
KCAddPersonViewController.m
//
// KCAddPersonViewController.m
// AddressBook
//
// kABPersonFirstNameProperty
// Copyright (c) 2014年 cmjstudio. All rights reserved.
//

#import "KCAddPersonViewController.h"
#import "KCContactTableViewController.h"

@interface KCAddPersonViewController ()

@property (weak, nonatomic) IBOutlet UITextField *firstName;
@property (weak, nonatomic) IBOutlet UITextField *lastName;
@property (weak, nonatomic) IBOutlet UITextField *workPhone;
@end

@implementation KCAddPersonViewController

- (void)viewDidLoad {
[super viewDidLoad];
[self setupUI];
}

#pragma mark - UI事件
- (IBAction)cancelClick:(UIBarButtonItem *)sender {
[self.delegate cancelEdit];
[self dismissViewControllerAnimated:YES completion:nil];
}

- (IBAction)doneClick:(UIBarButtonItem *)sender {
//调用代理方法
[self.delegate editPersonWithFirstName:self.firstName.text lastName:self.lastName.text workNumber:self.workPhone.text];

[self dismissViewControllerAnimated:YES completion:nil];
}

#pragma mark - 私有方法
-(void)setupUI{
if (self.recordID) {//如果ID不为0则认为是修改,此时需要初始化界面
self.firstName.text=self.firstNameText;
self.lastName.text=self.lastNameText;
self.workPhone.text=self.workPhoneText;
}
}
@end

长按保存图片到本地

`objc
//创建UILongPressGestureRecognizer UILongPressGestureRecognizer*longPG = [[UILongPressGestureRecognizeralloc]initWithTarget:selfaction:@selector(longAction:)
]; [selfaddGestureRecognizer:longPG];

}

//长按触发的方法
-(void)longAction:(UILongPressGestureRecognizer*)longPG
{

if(longPG.state==UIGestureRecognizerStateBegan)
{

   //创建UIAlertView对象
   UIAlertView*alert = [[UIAlertViewalloc]initWithTitle:@"提示"message:@"是否保存图片到本地"delegate:selfcancelButtonTitle:@"取消"otherButtonTitles:@"确定",nil];
   //调用show方法
    [alertshow];
   //释放
    [alertrelease];


}

}

  • (void)alertView:(UIAlertView*)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
    {
    if(buttonIndex ==1) {

    //UIImage写入本地的方法
    UIImageWriteToSavedPhotosAlbum(self.photo.image,nil,nil,nil);
    
    //创建UIAlertView对象
    UIAlertView*alert = [[UIAlertViewalloc]initWithTitle:@"提示"message:@"图片已保存成功"delegate:selfcancelButtonTitle:nilotherButtonTitles:nil];
    //调用show方法
     [alertshow];
    //释放
     [alertrelease];
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW,
    

    (int64_t)(1.0f*NSEC_PER_SEC)),dispatch_get_main_queue(), ^{

        [alertdismissWithClickedButtonIndex:0animated:YES];
    });
    

    }

    }

|