• 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
  • 相关阅读:
    每日总结
    每日总结
    每日总结
    每日总结
    每日总结
    每日总结
    每日总结
    每日总结
    每日总结
    Windows邮件添加QQ邮箱
  • 原文地址:https://www.cnblogs.com/xiaomoge/p/4201335.html
Copyright © 2020-2023  润新知