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 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
原文地址:https://www.cnblogs.com/xiaomoge/p/4201335.html