1.使用UITableView,实现联系人字母排序、点击字母跳转显示联系人组目录;
2.使用UISearchController,实现联系搜索,动态显示符合查询的联系人;
3.点击通讯录列表项,显示联系人信息(使用自定义模式化窗口类似与UIAlertView,使用UIwindow实现),点击拨号,可以直接拨打电话;
4.实现获取手机通讯录里面的联系人信息;
效果图如下:
获取联系人:
搜索页:
联系人信息:
主要显示页面代码:
//// ViewController.m// ContactionView//// Created by rong xiang on 16/4/26.// Copyright ©
2016年 hzz. All rights reserved.//#import "ViewController.h"#import#import "MobileAddressBook.h"#import "ChineseString.h"#import "CustomAlertView.h"#import "MyButton.h"@interface ViewController (){
NSMutableArray * listSection;
NSMutableArray * addressBookTemp;
NSMutableArray * listPhone;
NSMutableArray *_searchContacts;
//符合条件的搜索联系人 CustomAlertView * alertView;
UITableView *tableViewAddress;
UISearchBar * _searchBar;
UISearchDisplayController *_searchDisplayController;
}
@end@implementation ViewController-(void) loadView{
[super loadView];
tableViewAddress = [[UITableView alloc] initWithFrame:CGRectMake(0, 20, self.view.frame.size.width, self.view.frame.size.height - 20)];
[tableViewAddress setBackgroundColor:[UIColor colorWithRed:250.0f/255.0f green:250.0f/255.0f blue:250.0f/255.0f alpha:1.0]];
[tableViewAddress setSeparatorStyle:UITableViewCellSeparatorStyleNone];
[self.view addSubview:tableViewAddress];
[self addSearchBar];
}
- (void)viewDidLoad {
[super viewDidLoad];
//初始化显示对象 addressBookTemp = [[NSMutableArray alloc] init];
listSection = [[NSMutableArray alloc] init];
listPhone =[[NSMutableArray alloc] init];
NSMutableArray * listPhoneShow = [[NSMutableArray alloc] init];
tableViewAddress.delegate = self;
tableViewAddress.dataSource = self;
//获取通讯录联系人信息 [self getAddressBook];
//测试下的:初始化列表数据 [self initData];
//获取通讯录列表首字母,并排序 listSection = [ChineseString IndexArray:addressBookTemp];
//获取通讯录,并把通讯录对象按照首字母进行分组排序 listPhoneShow = [ChineseString LetterSortArray:addressBookTemp];
//把对应的同一个首字母下联系人对象按照首字母排序列表进行分组; NSInteger count = [listPhoneShow count];
NSArray * array = nil;
for(int i =0;
ii++){ i++){
-="" .systemversion="" _issearching="YES;
" _searchbar="" _searchbar.autocapitalizationtype="UITextAutocapitalizationTypeNone;
" _searchbar.delegate="self;
" _searchbar.placeholder="@"搜索联系人";
" _searchbar.showssearchresultsbutton="YES;
" _searchcontacts="" _searchdisplaycontroller="" _searchdisplaycontroller.delegate="self;
" _searchdisplaycontroller.searchresultsdatasource="self;
" _searchdisplaycontroller.searchresultsdelegate="self;
" _searchdisplaycontroller.searchresultstitle="@"没有符合的联系人";
" abaddressbookref="" add="" add.firstname="[listSection" addressbooks="nil;
" any="" arr="" array="[listPhoneShow" arrcount="[array" be="" bool="" can="" contact="nil;
" contact.firstname.uppercasestring="" contact.name.uppercasestring="" contact.tel="" count="[listPhone" didreceivememorywarning="" dispose="" goback="" i="0;
i<count;
i++){
" id="" if="" in="" initwithsearchbar:_searchbar="" int="" j="0;
j<" listphone="" mark="" mobileaddressbook="" nsarray="" nsinteger="" nsmutablearray="" nsstring="" nsuinteger="" of="" pragma="" recreated.="" resources="" self.navigationcontroller="" setactive:no="" showarr="" super="" tableviewaddress="" tableviewaddress.datasource="nil;
" tableviewaddress.delegate="nil;
" tableviewaddress.tableheaderview="_searchBar;
" tempstr="[array" that="" uidevice="" uisearchbar="">= 6.0) {
addressBooks = ABAddressBookCreateWithOptions(NULL, NULL);
//获取通讯录权限 dispatch_semaphore_t sema = dispatch_semaphore_create(0);
ABAddressBookRequestAccessWithCompletion(addressBooks, ^(bool granted, CFErrorRef error){
dispatch_semaphore_signal(sema);
}
);
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
// dispatch_release(sema);
}
else {
addressBooks = ABAddressBookCreate();
}
//获取通讯录中的所有人 CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBooks);
//通讯录中人数 CFIndex nPeople = ABAddressBookGetPersonCount(addressBooks);
//循环,获取每个人的个人信息 for (NSInteger i = 0;
i < nPeople;
i++) {
//新建一个addressBook model类 MobileAddressBook *addressBook = [[MobileAddressBook alloc] init];
//获取个人 ABRecordRef person = CFArrayGetValueAtIndex(allPeople, i);
//获取个人名字 CFTypeRef abName = ABRecordCopyValue(person, kABPersonFirstNameProperty);
CFTypeRef abLastName = ABRecordCopyValue(person, kABPersonLastNameProperty);
CFStringRef abFullName = ABRecordCopyCompositeName(person);
NSString *nameString = (__bridge NSString *)abName;
NSString *lastNameString = (__bridge NSString *)abLastName;
if ((__bridge id)abFullName != nil) {
nameString = (__bridge NSString *)abFullName;
}
else {
if ((__bridge id)abLastName != nil) {
nameString = [NSString stringWithFormat:@"%@ %@", nameString, lastNameString];
}
}
addressBook.name = nameString;
addressBook.recordID = (int)ABRecordGetRecordID(person);
;
ABPropertyID multiProperties[] = {
kABPersonPhoneProperty, kABPersonEmailProperty }
;
NSInteger multiPropertiesTotal = sizeof(multiProperties) / sizeof(ABPropertyID);
for (NSInteger j = 0;
j < multiPropertiesTotal;
j++) {
ABPropertyID property = multiProperties[j];
ABMultiValueRef valuesRef = ABRecordCopyValue(person, property);
NSInteger valuesCount = 0;
if (valuesRef != nil) valuesCount = ABMultiValueGetCount(valuesRef);
if (valuesCount == 0) {
CFRelease(valuesRef);
continue;
}
//获取电话号码和email for (NSInteger k = 0;
k < valuesCount;
k++) {
CFTypeRef value = ABMultiValueCopyValueAtIndex(valuesRef, k);
switch (j) {
case 0: {
// Phone number addressBook.tel = [(__bridge NSString*)value stringByReplacingOccurrencesOfString:@"-" withString:@""];
addressBook.tel = [addressBook.tel stringByReplacingOccurrencesOfString:@" " withString:@""];
addressBook.tel = [addressBook.tel stringByReplacingOccurrencesOfString:@"+86" withString:@""];
break;
}
case 1: {
// Email addressBook.email = (__bridge NSString*)value;
break;
}
}
CFRelease(value);
}
CFRelease(valuesRef);
}
//将个人信息添加到数组中,循环完成后addressBookTemp中包含所有联系人的信息 if(addressBook.tel.length != 11 ||addressBook.tel==nil||[addressBook.tel isEqual:@""]||[[addressBook.tel substringToIndex:3] isEqualToString:@"028"]) continue;
[addressBookTemp addObject:addressBook];
if (abName) CFRelease(abName);
if (abLastName) CFRelease(abLastName);
if (abFullName) CFRelease(abFullName);
}
}
-(void) initData{
MobileAddressBook * mab= [[MobileAddressBook alloc] init];
[mab setRecordID:1];
[mab setSectionNumber:0];
[mab setTel:@"15281008411"];
[mab setEmail:@""];
[mab setName:@"胡玉铉"];
[addressBookTemp addObject:mab];
mab= [[MobileAddressBook alloc] init];
[mab setRecordID:1];
[mab setSectionNumber:0];
[mab setTel:@"15281008411"];
[mab setEmail:@""];
[mab setName:@"hu铉"];
[addressBookTemp addObject:mab];
mab= [[MobileAddressBook alloc] init];
[mab setRecordID:2];
[mab setSectionNumber:0];
[mab setTel:@"15281008411"];
[mab setEmail:@""];
[mab setName:@"幸运星"];
[addressBookTemp addObject:mab];
mab= [[MobileAddressBook alloc] init];
[mab setRecordID:1];
[mab setSectionNumber:0];
[mab setTel:@"15281008411"];
[mab setEmail:@""];
[mab setName:@"夏铉"];
[addressBookTemp addObject:mab];
mab= [[MobileAddressBook alloc] init];
[mab setRecordID:1];
[mab setSectionNumber:0];
[mab setTel:@"15281008411"];
[mab setEmail:@""];
[mab setName:@"胡玉铉"];
[addressBookTemp addObject:mab];
mab= [[MobileAddressBook alloc] init];
[mab setRecordID:2];
[mab setSectionNumber:0];
[mab setTel:@"15281008411"];
[mab setEmail:@""];
[mab setName:@"斐雨雪"];
[addressBookTemp addObject:mab];
mab= [[MobileAddressBook alloc] init];
[mab setRecordID:2];
[mab setSectionNumber:0];
[mab setTel:@"15281008411"];
[mab setEmail:@""];
[mab setName:@"爱惜月"];
[addressBookTemp addObject:mab];
mab= [[MobileAddressBook alloc] init];
[mab setRecordID:2];
[mab setSectionNumber:0];
[mab setTel:@"15281008411"];
[mab setEmail:@""];
[mab setName:@"希"];
[addressBookTemp addObject:mab];
mab= [[MobileAddressBook alloc] init];
[mab setRecordID:1];
[mab setSectionNumber:0];
[mab setTel:@"15281008411"];
[mab setEmail:@""];
[mab setName:@"薛"];
[addressBookTemp addObject:mab];
mab= [[MobileAddressBook alloc] init];
[mab setRecordID:1];
[mab setSectionNumber:0];
[mab setTel:@"15281008411"];
[mab setEmail:@""];
[mab setName:@"陈铉"];
[addressBookTemp addObject:mab];
mab= [[MobileAddressBook alloc] init];
[mab setRecordID:1];
[mab setSectionNumber:0];
[mab setTel:@"15281008411"];
[mab setEmail:@""];
[mab setName:@"陈玉"];
[addressBookTemp addObject:mab];
mab= [[MobileAddressBook alloc] init];
[mab setRecordID:1];
[mab setSectionNumber:0];
[mab setTel:@"15281008411"];
[mab setEmail:@""];
[mab setName:@"陈雪月"];
[addressBookTemp addObject:mab];
mab= [[MobileAddressBook alloc] init];
[mab setRecordID:2];
[mab setSectionNumber:0];
[mab setTel:@"15281008411"];
[mab setEmail:@""];
[mab setName:@"陈婷"];
[addressBookTemp addObject:mab];
mab= [[MobileAddressBook alloc] init];
[mab setRecordID:2];
[mab setSectionNumber:0];
[mab setTel:@"15281008411"];
[mab setEmail:@""];
[mab setName:@"Wien 吃"];
[addressBookTemp addObject:mab];
mab= [[MobileAddressBook alloc] init];
[mab setRecordID:1];
[mab setSectionNumber:0];
[mab setTel:@"15281008411"];
[mab setEmail:@""];
[mab setName:@"wx"];
[addressBookTemp addObject:mab];
mab= [[MobileAddressBook alloc] init];
[mab setRecordID:1];
[mab setSectionNumber:0];
[mab setTel:@"15281008411"];
[mab setEmail:@""];
[mab setName:@"文娱x"];
[addressBookTemp addObject:mab];
mab= [[MobileAddressBook alloc] init];
[mab setRecordID:2];
[mab setSectionNumber:0];
[mab setTel:@"15281008411"];
[mab setEmail:@""];
[mab setName:@"张运出"];
[addressBookTemp addObject:mab];
mab= [[MobileAddressBook alloc] init];
[mab setRecordID:2];
[mab setSectionNumber:0];
[mab setTel:@"15281008411"];
[mab setEmail:@""];
[mab setName:@"#12443"];
[addressBookTemp addObject:mab];
}
#pragma --list 视图-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView{
if (tableView==self.searchDisplayController.searchResultsTableView) {
return 1;
}
return [listSection count];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
//如果当前是UISearchDisplayController内部的tableView则使用搜索数据 if (tableView==self.searchDisplayController.searchResultsTableView) {
return _searchContacts.count;
}
return [[listPhone objectAtIndex:section] count];
}
-(NSString *) tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
if (tableView==self.searchDisplayController.searchResultsTableView) {
return @"搜索结果";
}
NSString *title = [listSection objectAtIndex:section];
return title;
}
-(NSArray *) sectionIndexTitlesForTableView:(UITableView *) tableView{
if (tableView==self.searchDisplayController.searchResultsTableView) {
return [[NSArray alloc] init];
}
return listSection;
}
-(CGFloat) tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
if(section ==0) return 35;
return 30;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return 50;
}
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
// 组图标 UIImageView * imgHeader = nil;
// 联系人名称 UILabel * lblName = nil;
// 号码 UILabel * lblPhone = nil;
UIView * border = nil;
static NSString *CellIndentifier = @"phone";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIndentifier];
if(cell == nil) {
cell = [[UITableViewCell alloc] init];
[cell setRestorationIdentifier:CellIndentifier];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
[cell.contentView setBackgroundColor:tableViewAddress.backgroundColor];
imgHeader = [[UIImageView alloc] initWithFrame:CGRectMake(5, (cell.contentView.frame.size.height-40)/2, 40, 40)];
[imgHeader setImage:[UIImage imageNamed:@"head_default4.jpg"]];
imgHeader.tag = 99;
[cell.contentView addSubview:imgHeader];
lblName = [[UILabel alloc] initWithFrame:CGRectMake(imgHeader.frame.origin.x + imgHeader.frame.size.width +10, 5, cell.contentView.frame.size.width -imgHeader.frame.origin.x - imgHeader.frame.size.width*2 - 15, 21)];
[lblName setFont:[UIFont systemFontOfSize:14.0f]];
lblName.tag = 97;
[cell.contentView addSubview:lblName];
lblPhone = [[UILabel alloc] initWithFrame:CGRectMake(imgHeader.frame.origin.x + imgHeader.frame.size.width +10, 22, cell.contentView.frame.size.width -imgHeader.frame.origin.x - imgHeader.frame.size.width*2 - 15, 21)];
[lblPhone setFont:[UIFont systemFontOfSize:14.0f]];
lblPhone.tag = 96;
[cell.contentView addSubview:lblPhone];
border =[[UIView alloc] initWithFrame:CGRectMake(10, cell.frame.size.height - 1, cell.frame.size.width-35, 1)];
[border setBackgroundColor:[UIColor colorWithRed:200.0f/255.0f green:200.0f/255.0f blue:200.0f/255.0f alpha:1.0]];
border.tag = 95;
[cell.contentView addSubview:border];
}
else {
imgHeader = (UIImageView *)[cell.contentView viewWithTag:99];
lblName = (UILabel *)[cell.contentView viewWithTag:97];
lblPhone =(UILabel *)[cell.contentView viewWithTag:96];
border = (UIView*)[cell.contentView viewWithTag:95];
}
MobileAddressBook * address=nil;
// 如果显示通讯录列表 if(tableView!=self.searchDisplayController.searchResultsTableView){
address = [[listPhone objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
NSInteger arrayCount = [[listPhone objectAtIndex:indexPath.section] count];
if(arrayCount<=1 || indexPath.row==arrayCount-1) [border setHidden:YES];
else [border setHidden:NO];
}
else{
//如果显示搜索列表 address = [_searchContacts objectAtIndex:indexPath.row];
}
[lblName setText:address.name];
[lblPhone setText:address.tel];
return cell;
}
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
//显示联系人详情 MobileAddressBook * mab = nil;
BOOL isSearch = NO;
if(tableView == _searchDisplayController.searchResultsTableView){
mab = [_searchContacts objectAtIndex:indexPath.row];
isSearch = YES;
}
else{
mab = [[listPhone objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
isSearch = NO;
}
//弹出框,显示联系人信息 UIView * subView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 300, 100)];
[subView setBackgroundColor:[UIColor whiteColor]];
subView.center = CGPointMake((self.view.frame.size.width)/2, (self.view.frame.size.height-subView.frame.size.height)/2);
//添加头像 UIImageView * imgView = [[UIImageView alloc] initWithFrame:CGRectMake(17, 8, 45, 45)];
[imgView setImage:[UIImage imageNamed:@"headerimage"]];
[subView addSubview:imgView];
//添加姓名 UILabel * lblName =[[UILabel alloc] initWithFrame:CGRectMake(68, 19, 100, 21)];
[lblName setFont:[UIFont systemFontOfSize:15.0f]];
[lblName setText:mab.name];
[subView addSubview:lblName];
//添加“
电话”
标题 UILabel * lblTitle = [[UILabel alloc] initWithFrame:CGRectMake(20, 56, 68, 21)];
[lblTitle setText:@"电话"];
[lblTitle setFont:[UIFont systemFontOfSize:12.0f]];
[lblTitle setTextColor:[UIColor grayColor]];
[subView addSubview:lblTitle];
//添加电话号码显示 UILabel * lblPhoneNo = [[UILabel alloc] initWithFrame:CGRectMake(17, 72, 100, 21)];
[lblPhoneNo setText:mab.tel];
[lblPhoneNo setFont:[UIFont systemFontOfSize:14.0f]];
[subView addSubview:lblPhoneNo];
//添加按钮 MyButton * btn = [[MyButton alloc] initWithFrame:CGRectMake(170, 70, 52, 21)];
[btn setTitle:@"拨号" forState:UIControlStateNormal];
[btn setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
[btn addTarget:self action:@selector(Call:) forControlEvents:UIControlEventTouchUpInside];
NSMutableDictionary * dic = [[NSMutableDictionary alloc] init];
// [dic setValue:isSearch?@"YES":@"NO" forKey:@"isSearch"];
// [dic setValue:indexPath forKey:@"IndexPath"];
[dic setValue:mab forKey:@"Object"];
[btn setObjectDic:dic];
[subView addSubview:btn];
btn = [[MyButton alloc] initWithFrame:CGRectMake(240, 70, 52, 21)];
[btn setTitle:@"取消" forState:UIControlStateNormal];
[btn setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
[btn addTarget:self action:@selector(Cancel:) forControlEvents:UIControlEventTouchUpInside];
[subView addSubview:btn];
if(alertView != nil){
[alertView setHidden:NO];
[alertView.subviews[0] removeFromSuperview];
}
else alertView = [[CustomAlertView alloc] init];
alertView.subView = subView;
[alertView initView];
[alertView show];
}
//拨打电话-(void) Call:(id) sender{
MyButton * btn = sender;
[alertView dismiss];
[alertView setHidden:YES];
MobileAddressBook * addressBook = nil;
addressBook = [btn.ObjectDic objectForKey:@"Object"];
// NSIndexPath * indexPath = nil;
// BOOL isSearch = NO;
// NSMutableDictionary * dic = [btn ObjectDic];
// //获取联系人对象// isSearch = [[dic objectForKey:@"isSearch"] isEqualToString:@"YES"];
// indexPath = [dic objectForKey:@"IndexPath"];
// // if(isSearch){
// addressBook = [_searchContacts objectAtIndex:indexPath.row];
// }
else// addressBook = [[listPhone objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
NSMutableString * str=[[NSMutableString alloc] initWithFormat:@"tel:%@", addressBook.tel];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:str]];
}
-(void) Cancel:(id) sender{
[alertView dismiss];
[alertView setHidden:YES];
}
#pragma mark - UISearchDisplayController代理方法-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString{
[self searchDataWithKeyWord:searchString];
return YES;
}
#pragma mark 重写状态样式方法-(UIStatusBarStyle)preferredStatusBarStyle{
return UIStatusBarStyleLightContent;
}
#pragma mark 选中之前-(NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath{
[_searchBar resignFirstResponder];
//退出键盘 return indexPath;
}
@end
>
自定义alertview代码:
//// CustomAlertView.h// ContactionView//// Created by rong xiang on 16/4/28.// Copyright ©
2016年 hzz. All rights reserved.//#import@interface CustomAlertView : UIWindow@property (nonatomic,retain) UIView * subView;
// 显示-(void) show;
//消失-(void) dismiss;
-(void) initView;
@end
操作文件:
//// CustomAlertView.m// ContactionView//// Created by rong xiang on 16/4/28.// Copyright ©
2016年 hzz. All rights reserved.//#import "CustomAlertView.h"@implementation CustomAlertView@synthesize subView;
-(id) initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if(self){
self.windowLevel = UIWindowLevelAlert;
//这里,不能设置UIWindow的alpha属性,会影响里面的子view的透明度,这里可以用透明图片来设置背影半透明 self.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"transparent"]];
}
// if(subView==nil){
// subView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 80)];
// subView.backgroundColor = [UIColor lightGrayColor];
// subView.center = CGPointMake(160, 240);
// }
// [self addSubview:subView];
return self;
}
-(void) initView{
[self addSubview:subView];
self.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"transparent"]];
}
-(void)show{
[self makeKeyAndVisible];
}
-(void) dismiss{
[self resignKeyWindow];
}
//点击消失-(void) touchesBegan:(NSSet*)touches withEvent:(UIEvent *)event{
// [self dismiss];
}
-(void) touchesMoved:(NSSet*)touches withEvent:(UIEvent *)event{
}
-(void) touchesEnded:(NSSet*)touches withEvent:(UIEvent *)event{
}
@end
联系人对象:
//// MobileAddressBook.h// ContactionView//// Created by rong xiang on 16/4/26.// Copyright ©
2016年 hzz. All rights reserved.//#import@interface MobileAddressBook : NSObject@property NSInteger sectionNumber;
@property NSInteger recordID;
@property (nonatomic, retain) NSString *name;
@property (nonatomic,retain) NSString * firstName;
@property (nonatomic, retain) NSString *email;
@property (nonatomic, retain) NSString *tel;
@end
操作文件
//// MobileAddressBook.m// ContactionView//// Created by rong xiang on 16/4/26.// Copyright ©
2016年 hzz. All rights reserved.//#import "MobileAddressBook.h"@implementation MobileAddressBook@synthesize recordID,sectionNumber,name,tel,email,firstName;
@end