需求:实现一个简易私人通讯录,主要实现以下功能:
1、一个登录页面,一个显示联系人页面,一个添加联系人页面,一个编辑联系人页面;
2、登录页面:
2.1、当账号和密码输入框都有值的时候,登录按钮才能交互;
2.2、当取消勾选记住密码后,自动登录按钮也随之取消;
2.3、当勾选了自动登录按钮时,记住密码按钮也一同勾选;
2.4、点击登陆后,程序能够简单判断账号和密码是否正确,如果不正确则给出相应的提示,如果正确则跳转到联系人页面;
3、联系人页面:
3.1、可以添加联系人;
3.2、可以对当前联系人进行编辑;
3.3、编辑完成后,可以刷新页面;
3.4、可以删除某一联系人;
4、添加联系人页面:
4.1、当姓名和电话输入框都有值的时候,保存按钮才能交互;
4.2、当选择保存按钮之后,跳转到联系人页面,并显示添加的联系人信息;
5、编辑联系人页面:
5.1、当点击编辑按钮后,姓名和电话输入框才能输入;
5.2、当姓名和电话输入框有更改内容后,保存按钮才能交互;
5.3、当选择保存按钮之后,跳转到联系人页面,并编辑后的联系人信息;
实例文件结构:
具体实现代码:
Model:
1 // 2 // JWContact.h 3 // 12-29-Exercise 4 // 5 // Created by xiaomoge on 14/12/29. 6 // Copyright (c) 2014年 xiaomoge. All rights reserved. 7 // 8 9 #import <Foundation/Foundation.h> 10 11 @interface JWContact : NSObject <NSCoding> 12 /* 13 联系人姓名 14 */ 15 @property (nonatomic,copy) NSString *name; 16 /* 17 联系人电话 18 */ 19 @property (nonatomic,copy) NSString *tel; 20 @end
1 // 2 // JWContact.m 3 // 12-29-Exercise 4 // 5 // Created by xiaomoge on 14/12/29. 6 // Copyright (c) 2014年 xiaomoge. All rights reserved. 7 // 8 9 #import "JWContact.h" 10 11 @implementation JWContact 12 /* 13 NSKeyedArchiver归档中,属性如何保存 14 */ 15 - (void)encodeWithCoder:(NSCoder *)aCoder { 16 [aCoder encodeObject:self.name forKey:@"name"]; 17 [aCoder encodeObject:self.tel forKey:@"tel"]; 18 } 19 /* 20 NSKeyedArchiver归档中,属性如何读取 21 */ 22 - (id)initWithCoder:(NSCoder *)aDecoder { 23 if (self = [super init]) { 24 self.name = [aDecoder decodeObjectForKey:@"name"]; 25 self.tel = [aDecoder decodeObjectForKey:@"tel"]; 26 } 27 return self; 28 } 29 @end
Controller:
1 // 2 // ViewController.m 3 // 12-29-Exercise 4 // 5 // Created by xiaomoge on 14/12/29. 6 // Copyright (c) 2014年 xiaomoge. All rights reserved. 7 // 8 9 #import "ViewController.h" 10 #import "ContactViewController.h" 11 @interface ViewController () 12 /* 13 账号输入框 14 */ 15 @property (weak, nonatomic) IBOutlet UITextField *accountTextField; 16 /* 17 密码输入框 18 */ 19 @property (weak, nonatomic) IBOutlet UITextField *passWordTextField; 20 /* 21 记住密码开关 22 */ 23 @property (weak, nonatomic) IBOutlet UISwitch *rememberSwitch; 24 /* 25 自动登录开关 26 */ 27 @property (weak, nonatomic) IBOutlet UISwitch *autoLoginSwitch; 28 /* 29 登录按钮 30 */ 31 @property (weak, nonatomic) IBOutlet UIButton *loginBtn; 32 33 @end 34 35 @implementation ViewController 36 37 - (void)viewDidLoad { 38 [super viewDidLoad]; 39 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textFieldChange) name:UITextFieldTextDidChangeNotification object:self.accountTextField];//监听账号输入框是否有输入 40 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textFieldChange) name:UITextFieldTextDidChangeNotification object:self.passWordTextField];//监听密码输入框是否有输入 41 42 } 43 #pragma mark 监听文本框输入事件 44 - (void)textFieldChange { 45 if (self.accountTextField.text.length > 0 && self.passWordTextField.text.length > 0) { 46 self.loginBtn.enabled = YES;//如果账号和密码文本框有输入,那么登录按钮开启 47 } 48 } 49 #pragma mark 销毁文本框改变通知 50 - (void)dealloc { 51 [[NSNotificationCenter defaultCenter] removeObserver:self];//有订阅通知,也要有对应的销毁 52 } 53 #pragma mark 登录按钮事件 54 - (IBAction)loginBtnClick { 55 if ([self.accountTextField.text isEqual: @"damu"] && [self.passWordTextField.text isEqualToString:@"123"]) { 56 [self performSegueWithIdentifier:@"toContactSegue" sender:nil];//如果输入框里的值和存储的一致,那么根据segue标识来进行跳转页面 57 }else { 58 UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"账号或者密码不正确" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil]; 59 [alert show];//如果账号或密码不正确,暂时使用弹出窗口来提示 60 } 61 } 62 #pragma mark 注册按钮事件 63 - (IBAction)registBtnClick { 64 ContactViewController *contactVc = [[ContactViewController alloc] init]; 65 [self.navigationController pushViewController:contactVc animated:YES]; 66 } 67 #pragma mark 记住密码开关状态 68 - (IBAction)rememberSwitchChange { 69 if (self.rememberSwitch.on == YES && self.autoLoginSwitch.on == YES) { 70 [self.autoLoginSwitch setOn:NO animated:YES];//如果记住密码为开启状态,而自动登录也是开启状态,那么需要把自动登录改为关闭状态 71 } 72 } 73 #pragma mark 自动登录开关状态 74 - (IBAction)autoLoginSwitchChange { 75 if (self.autoLoginSwitch.on == YES && self.rememberSwitch.on == NO) { 76 [self.rememberSwitch setOn:YES animated:YES];//如果自动登录为开启状态,而记住密码是关闭状态,那么需要把记住密码改为开启状态 77 } 78 } 79 //传入跳转页面的一些数据 80 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 81 ContactViewController *con = segue.destinationViewController;//取得目标控制器 82 con.title = [NSString stringWithFormat:@"%@的通讯录",self.accountTextField.text]; 83 } 84 @end
1 // 2 // ContactViewController.m 3 // 12-29-Exercise 4 // 5 // Created by xiaomoge on 14/12/29. 6 // Copyright (c) 2014年 xiaomoge. All rights reserved. 7 // 8 9 #import "ContactViewController.h" 10 #import "JWContact.h" 11 #import "AddContactViewController.h" 12 #import "EditContactViewController.h" 13 @interface ContactViewController () <AddContactViewControllerDelegate,EditContactViewControllerDelegate> 14 @property (nonatomic,strong) NSMutableArray *contactDatas; 15 @property (nonatomic,copy) NSString *saveDatasPath; 16 @end 17 18 @implementation ContactViewController 19 #pragma mark - lazy load 20 - (NSMutableArray *)contactDatas { 21 if (!_contactDatas) { 22 _contactDatas = [NSKeyedUnarchiver unarchiveObjectWithFile:self.saveDatasPath]; 23 if (!_contactDatas) { 24 _contactDatas = [NSMutableArray array]; 25 } 26 } 27 return _contactDatas; 28 } 29 #pragma mark - 数据存储地址方法 30 - (NSString *)saveDatasPath { 31 if (!_saveDatasPath) { 32 _saveDatasPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"contactData.plist"]; 33 } 34 return _saveDatasPath; 35 } 36 - (void)viewDidLoad { 37 [super viewDidLoad]; 38 39 UIBarButtonItem *addItem = self.navigationItem.rightBarButtonItem;//获取到右边导航栏按钮 40 UIBarButtonItem *delItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemTrash target:self action:@selector(deleClick)];//添加一个垃圾桶按钮 41 self.navigationItem.rightBarButtonItems = @[addItem,delItem];//把右边按钮和垃圾桶按钮加到右边导航栏组中 42 } 43 //垃圾桶按钮是否进入编辑状态 44 - (void)deleClick { 45 [self.tableView setEditing:!self.tableView.editing animated:YES]; 46 } 47 #pragma mark - 编辑状态的方法 48 - (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath { 49 if(indexPath.row == 0) { 50 return UITableViewCellEditingStyleInsert;//设置编辑状态下的样式为添加 51 } 52 return UITableViewCellEditingStyleDelete;//设置为删除 53 } 54 - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { 55 if (editingStyle == UITableViewCellEditingStyleDelete) {//如果选择的是删除按钮 56 [self.contactDatas removeObjectAtIndex:indexPath.row];//删除数组联系人 57 [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];//删除tableView里的显示数据 58 } 59 [NSKeyedArchiver archiveRootObject:self.contactDatas toFile:self.saveDatasPath];//保存数据 60 } 61 #pragma mark - Table view data source 62 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 63 return self.contactDatas.count; 64 } 65 66 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 67 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"contactCell"]; 68 JWContact *contact = self.contactDatas[indexPath.row]; 69 cell.textLabel.text = contact.name; 70 cell.detailTextLabel.text = contact.tel; 71 return cell; 72 } 73 #pragma mark - AddContactViewControllerDelegate的方法 74 - (void)addContactWithviewController:(AddContactViewController *)addContactViewController contact:(JWContact *)contact { 75 //把传过来的数据加入到可变数组中 76 [self.contactDatas addObject:contact]; 77 78 //刷新界面 79 [self.tableView reloadData]; 80 [NSKeyedArchiver archiveRootObject:self.contactDatas toFile:self.saveDatasPath]; 81 //销毁源控制器 82 [self.navigationController popViewControllerAnimated:YES]; 83 } 84 #pragma mark - 85 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 86 id dist = segue.destinationViewController;//取得源控制器 87 if ([dist isKindOfClass:[AddContactViewController class]]) { 88 AddContactViewController *con = dist; 89 con.delegate = self;//设置代理 90 }else if ([dist isKindOfClass:[EditContactViewController class]]) { 91 EditContactViewController *edit = dist; 92 edit.delegate = self; 93 NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];//取得选中行的位置 94 edit.contact = self.contactDatas[indexPath.row];//把选中行的数据传给目标控制器 95 96 } 97 } 98 #pragma mark - EditContactViewControllerDelegate的方法 99 - (void)editController:(EditContactViewController *)controller contact:(JWContact *)contact { 100 [self.tableView reloadData]; 101 [NSKeyedArchiver archiveRootObject:self.contactDatas toFile:self.saveDatasPath]; 102 [self.navigationController popViewControllerAnimated:YES]; 103 } 104 @end
1 // 2 // AddContactViewController.h 3 // 12-29-Exercise 4 // 5 // Created by xiaomoge on 14/12/29. 6 // Copyright (c) 2014年 xiaomoge. All rights reserved. 7 // 8 9 #import <UIKit/UIKit.h> 10 @class JWContact,AddContactViewController; 11 @protocol AddContactViewControllerDelegate <NSObject> 12 13 @optional 14 - (void)addContactWithviewController:(AddContactViewController *)addContactViewController contact:(JWContact *)contact; 15 16 @end 17 @interface AddContactViewController : UIViewController 18 @property (nonatomic,strong) JWContact *contact; 19 @property (nonatomic,assign) id<AddContactViewControllerDelegate> delegate; 20 @end
// // AddContactViewController.m // 12-29-Exercise // // Created by xiaomoge on 14/12/29. // Copyright (c) 2014年 xiaomoge. All rights reserved. // #import "AddContactViewController.h" #import "JWContact.h" @interface AddContactViewController () @property (weak, nonatomic) IBOutlet UITextField *nameTextField; @property (weak, nonatomic) IBOutlet UITextField *telTextField; @property (weak, nonatomic) IBOutlet UIButton *addBtn; @end @implementation AddContactViewController - (void)viewDidLoad { [super viewDidLoad]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textFieldChange) name:UITextFieldTextDidChangeNotification object:self.nameTextField];//监听账号输入框是否有输入 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textFieldChange) name:UITextFieldTextDidChangeNotification object:self.telTextField];//监听密码输入框是否有输入 } - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self];//有监听就要有销毁 } - (IBAction)addBtnClick { //1、把输入的信息保存到模型数据中 if ([self.delegate respondsToSelector:@selector(addContactWithviewController:contact:)]) { JWContact *contact = [[JWContact alloc] init]; contact.name = self.nameTextField.text; contact.tel = self.telTextField.text; [self.delegate addContactWithviewController:self contact:contact]; } //2、销毁当前控制器 // [self.navigationController popViewControllerAnimated:YES]; } - (void)textFieldChange { if (self.nameTextField.text.length > 0 && self.telTextField.text.length > 0) { self.addBtn.enabled = YES;//如果文本框已经有了值,那么把添加按钮设为可用 } } - (IBAction)cancelClick:(id)sender { [self.navigationController popViewControllerAnimated:YES]; } @end
1 // 2 // EditContactViewController.h 3 // 12-29-Exercise 4 // 5 // Created by xiaomoge on 14/12/29. 6 // Copyright (c) 2014年 xiaomoge. All rights reserved. 7 // 8 9 #import <UIKit/UIKit.h> 10 @class JWContact,EditContactViewController; 11 @protocol EditContactViewControllerDelegate <NSObject> 12 13 @optional 14 - (void)editController:(EditContactViewController *)controller contact:(JWContact *)contact; 15 16 @end 17 @interface EditContactViewController : UIViewController 18 @property (nonatomic,strong) JWContact *contact; 19 @property (nonatomic,assign) id <EditContactViewControllerDelegate> delegate; 20 @end
1 // 2 // EditContactViewController.m 3 // 12-29-Exercise 4 // 5 // Created by xiaomoge on 14/12/29. 6 // Copyright (c) 2014年 xiaomoge. All rights reserved. 7 // 8 9 #import "EditContactViewController.h" 10 #import "JWContact.h" 11 @interface EditContactViewController () 12 13 @property (weak, nonatomic) IBOutlet UITextField *nameTextField; 14 @property (weak, nonatomic) IBOutlet UITextField *telTextField; 15 @property (weak, nonatomic) IBOutlet UIButton *saveBtn; 16 @property (weak, nonatomic) IBOutlet UIBarButtonItem *editItem; 17 18 @end 19 20 @implementation EditContactViewController 21 22 - (void)viewDidLoad { 23 [super viewDidLoad]; 24 self.telTextField.text = self.contact.tel; 25 self.nameTextField.text = self.contact.name; 26 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textFieldChange) name:UITextFieldTextDidChangeNotification object:self.nameTextField];//监听账号输入框是否有输入 27 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textFieldChange) name:UITextFieldTextDidChangeNotification object:self.telTextField];//监听密码输入框是否有输入 28 } 29 //监听输入框值是否变更 30 - (void)textFieldChange { 31 self.saveBtn.enabled = self.nameTextField.text.length && self.telTextField.text.length; 32 } 33 - (void)dealloc { 34 [[NSNotificationCenter defaultCenter] removeObserver:self];//销毁订阅通知 35 } 36 - (IBAction)editItemClick:(id)sender { 37 if ([self.editItem.title isEqualToString:@"编辑"]) { 38 self.editItem.title = @"取消"; 39 self.nameTextField.enabled = YES; 40 self.telTextField.enabled = YES; 41 self.saveBtn.hidden = NO; 42 }else { 43 self.editItem.title = @"编辑"; 44 self.nameTextField.enabled = NO; 45 self.telTextField.enabled = NO; 46 self.saveBtn.hidden = YES; 47 self.nameTextField.text = self.contact.name; 48 self.telTextField.text = self.contact.tel; 49 } 50 } 51 - (IBAction)canselItemClick:(id)sender { 52 [self.navigationController popViewControllerAnimated:YES]; 53 } 54 - (IBAction)saveClick { 55 if ([self.delegate respondsToSelector:@selector(editController:contact:)]) { 56 self.contact.name = self.nameTextField.text; 57 self.contact.tel = self.telTextField.text; 58 [self.delegate editController:self contact:self.contact]; 59 } 60 } 61 @end