首页 > 代码库 > UI进阶--UINavigationController和NSKeyedArchiver实现一个简易私人通讯录

UI进阶--UINavigationController和NSKeyedArchiver实现一个简易私人通讯录

需求:实现一个简易私人通讯录,主要实现以下功能:

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 JWContact12 /*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 @end34 35 @implementation ViewController36 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 @optional14 - (void)addContactWithviewController:(AddContactViewController *)addContactViewController contact:(JWContact *)contact;15 16 @end17 @interface AddContactViewController : UIViewController18 @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 @optional14 - (void)editController:(EditContactViewController *)controller contact:(JWContact *)contact;15 16 @end17 @interface EditContactViewController : UIViewController18 @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 @end19 20 @implementation EditContactViewController21 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

 

UI进阶--UINavigationController和NSKeyedArchiver实现一个简易私人通讯录