iOS之通讯录查看/添加/删除等基本功能实现

为了方便大家观看,我把每个文件里的代码都用分割线分开, 并且在代码中尽可能写非常详尽的注释😊


AppDelegate.m文件内容

咱们先来创建self.window和根视图控制器

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//定义我们工程整个的window
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];

ViewController *vc = [[ViewController alloc] init];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
//将导航栏nav设置为根视图控制器
self.window.rootViewController = nav;

[nav release];
[vc release];
[_window release];

return YES;
}

因为你创建了ViewController类型的对象,所以别忘了在头文件引入ViewController.h哦.


ViewController.m文件内容

#import "ViewController.h"
#import "DetailViewController.h"
#import "ADDFriendViewController.h"
//宏定义
#define IDENTIFIER @"WSScell"

@interface ViewController ()<UITableViewDelegate, UITableViewDataSource>//签署2个协议

@property(nonatomic, retain)UITableView *tableView;
@property(nonatomic, retain)NSMutableArray *dataSourceArray;

@end

@implementation ViewController

-(void)dealloc
{
    [_tableView release];
    [_dataSourceArray release];
    [super dealloc];
}

这里我为大家一步步解释:

#import "DetailViewController.h"
#import "ADDFriendViewController.h"

这是咱们的通讯录需要用导航控制器navigationController来推出的两个界面, 他们俩分别是联系人详情界面和添加联系人(以及输入详细信息)界面

#define IDENTIFIER @"WSScell"

这是我们定义的一个宏,会便利于我们一会某个方法的书写,下面会找到

@interface ViewController ()<UITableViewDelegate, UITableViewDataSource>

这是签署UITableView的两个协议

剩下的部分是我们创建的两个对象(表视图, 数据源数组), 以及他们的释放, 我相信小伙伴们这个都看的懂


- (void)viewDidLoad {
[super viewDidLoad];

//添加背景颜色
self.view.backgroundColor = [UIColor whiteColor];
//设置该界面(该ViewController)的标题
self.title = @"通讯录";

//设置导航栏透明度为no
self.navigationController.navigationBar.translucent = NO;
//设置导航栏navigationBar颜色
self.navigationController.navigationBar.barTintColor = [UIColor colorWithRed:0.33 green:0.33 blue:0.34 alpha:1.00];
//设置navigationBar的风格为黑色风格(这会将状态栏颜色以及标题颜色变为白色)比较美观
self.navigationController.navigationBar.barStyle = UIBarStyleBlack;

//右侧添加按钮(UIBarButton类型为Add,即添加)
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(didClickedRightButton:)];
self.navigationController.navigationBar.tintColor = [UIColor whiteColor];

//左侧添加按钮(类型为系统类型editButtonItem,即编辑)
self.navigationItem.leftBarButtonItem = self.editButtonItem;

//我们在头文件中签署了两个协议还记得吧,这里我们为两个协议分别设置代理人为self
self.tableView.delegate = self;
self.tableView.dataSource = self;
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:IDENTIFIER];
}

我在代码中几乎每一行都加上了注释,以便于大家的理解观看. 上面最后一行是,注册cell并且设置cell的重用标识符是@"WSScell",这里的@"WSScell"我们在头文件定义过宏定义的

-(void)loadView {
[super loadView];
//创建搭载通讯录的表视图tableView, 并设置初始高度为50.0
self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height - 64) style:UITableViewStylePlain];
self.tableView.rowHeight = 50.0f;

[self.view addSubview:_tableView];
[_tableView release];

self.dataSourceArray = [NSMutableArray arrayWithContentsOfFile:@"/Users/dllo/Desktop/王少帅/UI/课后作业/王少帅10_UITableView/王少帅10_UITableView/Student.plist"];
}

这里我说一下, 最后一行这一大串子大家可能看不懂, 这里是一个Student.plist文件,里面放的是一个存放联系人信息字典的数组, 每个字典有6个键值对,表示一个联系人的整体信息, (因为文件不能上传, 所以只能让你们在这看), 如图:

Snip20160413_1.png

接下来我们来看两个因签署了<UITableViewDataSource>协议而必须执行的方法

//(1)返回值为创建的表视图的行数
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.dataSourceArray.count;
}
//(2)确定表视图每个cell的内容(这个方法每出现一个cell都走一次)
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//根据重用标识符去重用池里找出对应cell, (重用池非常棒, 节省大量内存)
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:IDENTIFIER];
NSDictionary *dic = [self.dataSourceArray objectAtIndex:indexPath.row];
cell.textLabel.text = [dic valueForKey:@"name"];
return cell;
}

这个方法主要的核心在于创建一个字典dic接收数据源数组特定indexPath.row的元素,
并且将该cell的textField用dic的名字key赋值(就是在通讯录第一页上用表视图显示每个联系人的名字.
.
以下是一些需要写的关于tableView编辑的方法

- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
[super setEditing:editing animated:animated];
//让tableView处于可编辑状态
[self.tableView setEditing:editing animated:animated];
}

.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
//设定全部cell都可编辑
return YES;
}
.
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
//设置cell可支持的编辑样式
return UITableViewCellEditingStyleDelete;
}

下面这个方法设置编辑完成的逻辑

-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
//判断编辑的样式(判断是否是删除样式)
if (editingStyle == UITableViewCellEditingStyleDelete)
{
    //如果是删除样式,删除数据源(数组对应的元素(字典))
    [self.dataSourceArray removeObjectAtIndex:indexPath.row];
    //刷新tableView
    [self.tableView reloadData];
}
}

下面为导航栏右侧写点击方法(推出添加联系人界面)

-(void)didClickedRightButton:(UIBarButtonItem *)button
{
ADDFriendViewController *addfvc = [[ADDFriendViewController alloc] init];
//利用block传值, 将添加联系人界面中的联系人信息用字典dic传回主界面
addfvc.box = ^(NSDictionary *dic)
{
    NSDictionary *dictionary = [NSDictionary dictionaryWithDictionary:dic];
    [self.dataSourceArray addObject:dictionary];
    [self.tableView reloadData];
    NSLog(@"%@", dic);
};
//推出添加联系人界面
[self.navigationController pushViewController:addfvc animated:YES];
[addfvc release];
}

下面点击cell推出该cell联系人对应的详情界面

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
DetailViewController *dvc = [[DetailViewController alloc] init];
//推出详情界面
[self.navigationController pushViewController:dvc animated:YES];
//创建一个字典接收从数据源数组指定下标取出的字典元素, 用该字典内容布置详细介面信息
dvc.detailDic = [self.dataSourceArray objectAtIndex:indexPath.row];
[dvc release];
}

DetailViewController.h 文件内容

@interface DetailViewController : UIViewController
@property(nonatomic, retain)NSDictionary *detailDic;
@end

这里只有一步, 就是创建详细信息字典这个属性, 用来接收从主界面传过来的联系人信息


DetailViewController.m 文件内容

首先还是老问题了, 注意释放(因为作者是在MRC可是下编程的)
- (void)dealloc
{
[_detailDic release];
[super dealloc];
}

在viewDidLoad中赋予背景颜色(在这里作者说一下, 如果新推出来一个界面不赋予背景颜色的话必然会在模拟器刚推出来的时候卡顿一下, 真机也是如此), 所以每一个新的界面第一步都先赋予白色背景颜色是一个很好地习惯哦
- (void)viewDidLoad
{
[super viewDidLoad];

self.view.backgroundColor = [UIColor whiteColor];
//设置导航栏标题为在详细信息字典dic中取出来的name对用的value, 也就是这个联系人的名字
self.navigationItem.title = [_detailDic valueForKey:@"name"];
}
联系人详情界面导航栏特写.png

下面是loadView里面走的程序

-(void)loadView
{
[super loadView];

UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(20, 20, 100, 100)];
imageView.backgroundColor = [UIColor colorWithRed:0.95 green:0.95 blue:0.95 alpha:1.00];
imageView.layer.cornerRadius = 50.0f;
imageView.layer.masksToBounds = YES;
imageView.image = [UIImage imageNamed:@"touxiang@2x"];
[self.view addSubview:imageView];
[imageView release];

UILabel *ageLabel = [[UILabel alloc] initWithFrame:CGRectMake(30, 140, 200, 30)];
ageLabel.text = [NSString stringWithFormat:@"年龄 : %@", [_detailDic valueForKey:@"age"]];
[self.view addSubview:ageLabel];
[ageLabel release];

UILabel *numberLabel = [[UILabel alloc] initWithFrame:CGRectMake(30, 180, 200, 30)];
numberLabel.text = [NSString stringWithFormat:@"学号 : %@", [_detailDic valueForKey:@"number"]];
[self.view addSubview:numberLabel];
[numberLabel release];

UILabel *genderLabel = [[UILabel alloc] initWithFrame:CGRectMake(30, 220, 200, 30)];
genderLabel.text = [NSString stringWithFormat:@"性别 : %@", [_detailDic valueForKey:@"gender"]];
[self.view addSubview:genderLabel];
[genderLabel release];

UILabel *photoLabel = [[UILabel alloc] initWithFrame:CGRectMake(30, 260, 200, 30)];
photoLabel.text = [NSString stringWithFormat:@"照片 : %@", [_detailDic valueForKey:@"photo"]];
[self.view addSubview:photoLabel];
[photoLabel release];

UILabel *hobbyLabel = [[UILabel alloc] initWithFrame:CGRectMake(30, 300, 200, 30)];
hobbyLabel.text = [NSString stringWithFormat:@"爱好 : %@", [_detailDic valueForKey:@"hobby"]];
[self.view addSubview:hobbyLabel];
[hobbyLabel release];
}

在loadView界面, 需要根据联系人详细字典, 搭载了包括name, age, number, gender, photo, hobby这6个对象,并按照比较美观的样式进行修改(这里全看个人审美), 重点是其中的内容, 例如hobbyLabel的text就是根据联系人详细信息字典中hobby对应的value进行定义的,其他也是如此, 让大家看一下界面效果:

联系人详情界面.png

到这里联系人详解界面基本就完成了, 点击哪个cell, 该联系人详情界面的信息会根据传过来的字典内容进行赋值


ADDFriendViewController.h 文件内容

typedef void(^MyBox)(NSDictionary *);

@interface ADDFriendViewController : UIViewController

@property(nonatomic, copy)MyBox box;

@end

这里我们定义了block属性(为了进行block传值), 并且对block进行重定义(为了方便书写)

@interface ADDFriendViewController ()
@property(nonatomic, retain)UITextField *nameTextField;
@property(nonatomic, retain)UITextField *ageTextField;
@property(nonatomic, retain)UITextField *numberTextField;
@property(nonatomic, retain)UITextField *genderTextField;
@property(nonatomic, retain)UITextField *photoTextField;
@property(nonatomic, retain)UITextField *hobbyTextField;
@property(nonatomic, retain)NSDictionary *dic;
@end

声明6个属性
- (void)dealloc
{
Block_release(_box);
[_nameTextField release];
[_ageTextField release];
[_numberTextField release];
[_genderTextField release];
[_photoTextField release];
[_hobbyTextField release];
[_dic release];
[super dealloc];
}
release6个属性

- (void)viewDidLoad {
[super viewDidLoad];

self.view.backgroundColor = [UIColor whiteColor];
self.navigationItem.title = @"添加联系人";

_nameTextField = [[UITextField alloc] initWithFrame:CGRectMake(87, 20, 200, 30)];
_nameTextField.borderStyle = UITextBorderStyleRoundedRect;
_nameTextField.placeholder = @"请输入联系人姓名";
[self.view addSubview:_nameTextField];
[_nameTextField release];

_ageTextField = [[UITextField alloc] initWithFrame:CGRectMake(87, 60, 200, 30)];
_ageTextField.borderStyle = UITextBorderStyleRoundedRect;
_ageTextField.placeholder = @"请输入联系人年龄";
[self.view addSubview:_ageTextField];
[_ageTextField release];

_numberTextField = [[UITextField alloc] initWithFrame:CGRectMake(87, 100, 200, 30)];
_numberTextField.borderStyle = UITextBorderStyleRoundedRect;
_numberTextField.placeholder = @"请输入联系人编号";
[self.view addSubview:_numberTextField];
[_numberTextField release];

_genderTextField = [[UITextField alloc] initWithFrame:CGRectMake(87, 140, 200, 30)];
_genderTextField.borderStyle = UITextBorderStyleRoundedRect;
_genderTextField.placeholder = @"请输入联系人性别";
[self.view addSubview:_genderTextField];
[_genderTextField release];

_photoTextField = [[UITextField alloc] initWithFrame:CGRectMake(87, 180, 200, 30)];
_photoTextField.borderStyle = UITextBorderStyleRoundedRect;
_photoTextField.placeholder = @"请设置联系人照片";
[self.view addSubview:_photoTextField];
[_photoTextField release];

_hobbyTextField = [[UITextField alloc] initWithFrame:CGRectMake(87, 220, 200, 30)];
_hobbyTextField.borderStyle = UITextBorderStyleRoundedRect;
_hobbyTextField.placeholder = @"请输入联系人爱好";
[self.view addSubview:_hobbyTextField];
[_hobbyTextField release];

UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
button.frame = CGRectMake(107, 280, 160, 20);
[button addTarget:self action:@selector(didClickedAddbutton:) forControlEvents:UIControlEventTouchUpInside];
[button setTitle:@"创建联系人" forState:UIControlStateNormal];
[self.view addSubview:button];
}

以上是搭载这个界面, 这里不详说
.
最主要的部分来了, 就是下面的这个, 为传建联系人按钮添加点击方法 ,block的逆向传值, 并且传的是一个字典dic

-(void)didClickedAddbutton:(UIButton *)button
{
//判断添加的联系人name栏是否为空
if ([self.nameTextField.text isEqualToString:@""])
{
    //如果name栏为空, 则弹出提示框提示
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提  示" message:@"联系人姓名不能为空" preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction *actionIKnow = [UIAlertAction actionWithTitle:@"知道了👌" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        nil;
    }];
    [alertController addAction:actionIKnow];
    [self showDetailViewController:alertController sender:nil];
}
else
{
    //如果name不为空,则可以创建该联系人, 并且将该联系人信息以字典的形式打包进block(我们的block名字为box), 并且将信息传回主界面, 然后pop回前一页(联系人主页面)
    self.dic = [NSDictionary dictionaryWithObjectsAndKeys: self.nameTextField.text, @"name", self.ageTextField.text, @"age", self.numberTextField.text, @"number", self.genderTextField.text, @"gender", self.photoTextField.text, @"photo", self.hobbyTextField.text, @"hobby", nil];
    [self.nameTextField retain];
    [self.ageTextField retain];
    [self.genderTextField retain];
    [self.photoTextField retain];
    [self.numberTextField retain];
    [self.hobbyTextField retain];
    self.box(self.dic);
    [self.navigationController popViewControllerAnimated:YES];
}
}

创建联系人界面.png
通讯录主页.png

如果添加空name的联系人, 则会弹出警告提示框


警告提示框.png

联系人主界面, 左上角Edit按钮, 点击后可进入选择删除

联系人主界面, 左上角Edit按钮.png
点击Edit按钮后, 可进行联系人的删除操作.png

真的是写的详尽的不能再详尽了, 写的可能有的地方掺杂了个人观念, 毕竟不是IOS真正的大神, 理解不是特别渗透, 不过希望我的用心能帮助大家😊

zhi

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,001评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,210评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,874评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,001评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,022评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,005评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,929评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,742评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,193评论 1 309
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,427评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,583评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,305评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,911评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,564评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,731评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,581评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,478评论 2 352

推荐阅读更多精彩内容

  • 资料收集自网络... 1.通讯录• 学习目的:控制器跳转,控制器之间传值,数据存储2.项目演示:(4个界面,交给4...
    b485c88ab697阅读 310评论 0 0
  • *面试心声:其实这些题本人都没怎么背,但是在上海 两周半 面了大约10家 收到差不多3个offer,总结起来就是把...
    Dove_iOS阅读 27,139评论 30 470
  • 2017.02.22 可以练习,每当这个时候,脑袋就犯困,我这脑袋真是神奇呀,一说让你做事情,你就犯困,你可不要太...
    Carden阅读 1,342评论 0 1
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,090评论 4 62
  • 这个系列从去年开始断断续续地写,今年要继续写下去,争取写到100辑。 把这个系列在豆瓣上做了一个豆列,如果想看之前...
    柳二白阅读 245评论 0 3