為了方便大家觀看,我把每個文件里的代碼都用分割線分開, 并且在代碼中盡可能寫非常詳盡的注釋??
AppDelegate.m文件內(nèi)容
咱們先來創(chuàng)建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];
//將導(dǎo)航欄nav設(shè)置為根視圖控制器
self.window.rootViewController = nav;
[nav release];
[vc release];
[_window release];
return YES;
}
因為你創(chuàng)建了ViewController類型的對象,所以別忘了在頭文件引入ViewController.h哦.
ViewController.m文件內(nèi)容
#import "ViewController.h"
#import "DetailViewController.h"
#import "ADDFriendViewController.h"
//宏定義
#define IDENTIFIER @"WSScell"
@interface ViewController ()<UITableViewDelegate, UITableViewDataSource>//簽署2個協(xié)議
@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"
這是咱們的通訊錄需要用導(dǎo)航控制器navigationController來推出的兩個界面, 他們倆分別是聯(lián)系人詳情界面和添加聯(lián)系人(以及輸入詳細信息)界面
#define IDENTIFIER @"WSScell"
這是我們定義的一個宏,會便利于我們一會某個方法的書寫,下面會找到
@interface ViewController ()<UITableViewDelegate, UITableViewDataSource>
這是簽署UITableView的兩個協(xié)議
剩下的部分是我們創(chuàng)建的兩個對象(表視圖, 數(shù)據(jù)源數(shù)組), 以及他們的釋放, 我相信小伙伴們這個都看的懂
- (void)viewDidLoad {
[super viewDidLoad];
//添加背景顏色
self.view.backgroundColor = [UIColor whiteColor];
//設(shè)置該界面(該ViewController)的標(biāo)題
self.title = @"通訊錄";
//設(shè)置導(dǎo)航欄透明度為no
self.navigationController.navigationBar.translucent = NO;
//設(shè)置導(dǎo)航欄navigationBar顏色
self.navigationController.navigationBar.barTintColor = [UIColor colorWithRed:0.33 green:0.33 blue:0.34 alpha:1.00];
//設(shè)置navigationBar的風(fēng)格為黑色風(fēng)格(這會將狀態(tài)欄顏色以及標(biāo)題顏色變?yōu)榘咨?比較美觀
self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
//右側(cè)添加按鈕(UIBarButton類型為Add,即添加)
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(didClickedRightButton:)];
self.navigationController.navigationBar.tintColor = [UIColor whiteColor];
//左側(cè)添加按鈕(類型為系統(tǒng)類型editButtonItem,即編輯)
self.navigationItem.leftBarButtonItem = self.editButtonItem;
//我們在頭文件中簽署了兩個協(xié)議還記得吧,這里我們?yōu)閮蓚€協(xié)議分別設(shè)置代理人為self
self.tableView.delegate = self;
self.tableView.dataSource = self;
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:IDENTIFIER];
}
我在代碼中幾乎每一行都加上了注釋,以便于大家的理解觀看. 上面最后一行是,注冊cell并且設(shè)置cell的重用標(biāo)識符是@"WSScell",這里的@"WSScell"我們在頭文件定義過宏定義的
-(void)loadView {
[super loadView];
//創(chuàng)建搭載通訊錄的表視圖tableView, 并設(shè)置初始高度為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/課后作業(yè)/王少帥10_UITableView/王少帥10_UITableView/Student.plist"];
}
這里我說一下, 最后一行這一大串子大家可能看不懂, 這里是一個Student.plist文件,里面放的是一個存放聯(lián)系人信息字典的數(shù)組, 每個字典有6個鍵值對,表示一個聯(lián)系人的整體信息, (因為文件不能上傳, 所以只能讓你們在這看), 如圖:
接下來我們來看兩個因簽署了<UITableViewDataSource>協(xié)議而必須執(zhí)行的方法
//(1)返回值為創(chuàng)建的表視圖的行數(shù)
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.dataSourceArray.count;
}
//(2)確定表視圖每個cell的內(nèi)容(這個方法每出現(xiàn)一個cell都走一次)
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//根據(jù)重用標(biāo)識符去重用池里找出對應(yīng)cell, (重用池非常棒, 節(jié)省大量內(nèi)存)
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:IDENTIFIER];
NSDictionary *dic = [self.dataSourceArray objectAtIndex:indexPath.row];
cell.textLabel.text = [dic valueForKey:@"name"];
return cell;
}
這個方法主要的核心在于創(chuàng)建一個字典dic接收數(shù)據(jù)源數(shù)組特定indexPath.row的元素,
并且將該cell的textField用dic的名字key賦值(就是在通訊錄第一頁上用表視圖顯示每個聯(lián)系人的名字.
.
以下是一些需要寫的關(guān)于tableView編輯的方法
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
[super setEditing:editing animated:animated];
//讓tableView處于可編輯狀態(tài)
[self.tableView setEditing:editing animated:animated];
}
.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
//設(shè)定全部cell都可編輯
return YES;
}
.
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
//設(shè)置cell可支持的編輯樣式
return UITableViewCellEditingStyleDelete;
}
下面這個方法設(shè)置編輯完成的邏輯
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
//判斷編輯的樣式(判斷是否是刪除樣式)
if (editingStyle == UITableViewCellEditingStyleDelete)
{
//如果是刪除樣式,刪除數(shù)據(jù)源(數(shù)組對應(yīng)的元素(字典))
[self.dataSourceArray removeObjectAtIndex:indexPath.row];
//刷新tableView
[self.tableView reloadData];
}
}
下面為導(dǎo)航欄右側(cè)寫點擊方法(推出添加聯(lián)系人界面)
-(void)didClickedRightButton:(UIBarButtonItem *)button
{
ADDFriendViewController *addfvc = [[ADDFriendViewController alloc] init];
//利用block傳值, 將添加聯(lián)系人界面中的聯(lián)系人信息用字典dic傳回主界面
addfvc.box = ^(NSDictionary *dic)
{
NSDictionary *dictionary = [NSDictionary dictionaryWithDictionary:dic];
[self.dataSourceArray addObject:dictionary];
[self.tableView reloadData];
NSLog(@"%@", dic);
};
//推出添加聯(lián)系人界面
[self.navigationController pushViewController:addfvc animated:YES];
[addfvc release];
}
下面點擊cell推出該cell聯(lián)系人對應(yīng)的詳情界面
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
DetailViewController *dvc = [[DetailViewController alloc] init];
//推出詳情界面
[self.navigationController pushViewController:dvc animated:YES];
//創(chuàng)建一個字典接收從數(shù)據(jù)源數(shù)組指定下標(biāo)取出的字典元素, 用該字典內(nèi)容布置詳細介面信息
dvc.detailDic = [self.dataSourceArray objectAtIndex:indexPath.row];
[dvc release];
}
DetailViewController.h 文件內(nèi)容
@interface DetailViewController : UIViewController
@property(nonatomic, retain)NSDictionary *detailDic;
@end
這里只有一步, 就是創(chuàng)建詳細信息字典這個屬性, 用來接收從主界面?zhèn)鬟^來的聯(lián)系人信息
DetailViewController.m 文件內(nèi)容
首先還是老問題了, 注意釋放(因為作者是在MRC可是下編程的)
- (void)dealloc
{
[_detailDic release];
[super dealloc];
}
在viewDidLoad中賦予背景顏色(在這里作者說一下, 如果新推出來一個界面不賦予背景顏色的話必然會在模擬器剛推出來的時候卡頓一下, 真機也是如此), 所以每一個新的界面第一步都先賦予白色背景顏色是一個很好地習(xí)慣哦
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
//設(shè)置導(dǎo)航欄標(biāo)題為在詳細信息字典dic中取出來的name對用的value, 也就是這個聯(lián)系人的名字
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:@"學(xué)號 : %@", [_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界面, 需要根據(jù)聯(lián)系人詳細字典, 搭載了包括name, age, number, gender, photo, hobby這6個對象,并按照比較美觀的樣式進行修改(這里全看個人審美), 重點是其中的內(nèi)容, 例如hobbyLabel的text就是根據(jù)聯(lián)系人詳細信息字典中hobby對應(yīng)的value進行定義的,其他也是如此, 讓大家看一下界面效果:
到這里聯(lián)系人詳解界面基本就完成了, 點擊哪個cell, 該聯(lián)系人詳情界面的信息會根據(jù)傳過來的字典內(nèi)容進行賦值
ADDFriendViewController.h 文件內(nèi)容
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 = @"添加聯(lián)系人";
_nameTextField = [[UITextField alloc] initWithFrame:CGRectMake(87, 20, 200, 30)];
_nameTextField.borderStyle = UITextBorderStyleRoundedRect;
_nameTextField.placeholder = @"請輸入聯(lián)系人姓名";
[self.view addSubview:_nameTextField];
[_nameTextField release];
_ageTextField = [[UITextField alloc] initWithFrame:CGRectMake(87, 60, 200, 30)];
_ageTextField.borderStyle = UITextBorderStyleRoundedRect;
_ageTextField.placeholder = @"請輸入聯(lián)系人年齡";
[self.view addSubview:_ageTextField];
[_ageTextField release];
_numberTextField = [[UITextField alloc] initWithFrame:CGRectMake(87, 100, 200, 30)];
_numberTextField.borderStyle = UITextBorderStyleRoundedRect;
_numberTextField.placeholder = @"請輸入聯(lián)系人編號";
[self.view addSubview:_numberTextField];
[_numberTextField release];
_genderTextField = [[UITextField alloc] initWithFrame:CGRectMake(87, 140, 200, 30)];
_genderTextField.borderStyle = UITextBorderStyleRoundedRect;
_genderTextField.placeholder = @"請輸入聯(lián)系人性別";
[self.view addSubview:_genderTextField];
[_genderTextField release];
_photoTextField = [[UITextField alloc] initWithFrame:CGRectMake(87, 180, 200, 30)];
_photoTextField.borderStyle = UITextBorderStyleRoundedRect;
_photoTextField.placeholder = @"請設(shè)置聯(lián)系人照片";
[self.view addSubview:_photoTextField];
[_photoTextField release];
_hobbyTextField = [[UITextField alloc] initWithFrame:CGRectMake(87, 220, 200, 30)];
_hobbyTextField.borderStyle = UITextBorderStyleRoundedRect;
_hobbyTextField.placeholder = @"請輸入聯(lián)系人愛好";
[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:@"創(chuàng)建聯(lián)系人" forState:UIControlStateNormal];
[self.view addSubview:button];
}
以上是搭載這個界面, 這里不詳說
.
最主要的部分來了, 就是下面的這個, 為傳建聯(lián)系人按鈕添加點擊方法 ,block的逆向傳值, 并且傳的是一個字典dic
-(void)didClickedAddbutton:(UIButton *)button
{
//判斷添加的聯(lián)系人name欄是否為空
if ([self.nameTextField.text isEqualToString:@""])
{
//如果name欄為空, 則彈出提示框提示
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提 示" message:@"聯(lián)系人姓名不能為空" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *actionIKnow = [UIAlertAction actionWithTitle:@"知道了??" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
nil;
}];
[alertController addAction:actionIKnow];
[self showDetailViewController:alertController sender:nil];
}
else
{
//如果name不為空,則可以創(chuàng)建該聯(lián)系人, 并且將該聯(lián)系人信息以字典的形式打包進block(我們的block名字為box), 并且將信息傳回主界面, 然后pop回前一頁(聯(lián)系人主頁面)
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的聯(lián)系人, 則會彈出警告提示框
聯(lián)系人主界面, 左上角Edit按鈕, 點擊后可進入選擇刪除
真的是寫的詳盡的不能再詳盡了, 寫的可能有的地方摻雜了個人觀念, 畢竟不是IOS真正的大神, 理解不是特別滲透, 不過希望我的用心能幫助大家??
zhi