1.使用UITableView,实现联系人字母排序、点击字母跳转显示联系人组目录;
2.使用UISearchController,实现联系搜索,动态显示符合查询的联系人;
3.点击通讯录列表项,显示联系人信息(使用自定义模式化窗口类似与UIAlertView,使用UIwindow实现),点击拨号,可以直接拨打电话;
4.实现获取手机通讯录里面的联系人信息;
详情见资源:http://download.csdn.net/detail/u011622479/9505751
效果图如下:
获取联系人:
搜索页:
联系人信息:
主要显示页面代码:
//
// 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;i= 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
//
// 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