为了方便大家观看,我把每个文件里的代码都用分割线分开, 并且在代码中尽可能写非常详尽的注释😊
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个键值对,表示一个联系人的整体信息, (因为文件不能上传, 所以只能让你们在这看), 如图:
接下来我们来看两个因签署了<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"];
}
下面是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进行定义的,其他也是如此, 让大家看一下界面效果:
到这里联系人详解界面基本就完成了, 点击哪个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];
}
}
如果添加空name的联系人, 则会弹出警告提示框
联系人主界面, 左上角Edit按钮, 点击后可进入选择删除
真的是写的详尽的不能再详尽了, 写的可能有的地方掺杂了个人观念, 毕竟不是IOS真正的大神, 理解不是特别渗透, 不过希望我的用心能帮助大家😊
zhi