IOS第13天(3,私人通讯录,登陆状态数据存储,数据缓存, cell的滑动删除,进入编辑模式,单个位置刷新 )

*****联系人的界面的优化 HMContactsTableViewController.m

#import "HMContactsTableViewController.h"
#import "HMAddViewController.h"

#import "HMEditViewController.h"

#import "HMContactCell.h"


#import "HMContact.h"

#define HMFilePath [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0] stringByAppendingPathComponent:@"contact.data"]

@interface HMContactsTableViewController ()<UIActionSheetDelegate,HMAddViewControllerDelgegate,HMEditViewControllerDelegate>

@property (nonatomic, strong) NSMutableArray *contacts;

@end

@implementation HMContactsTableViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    // 移除分割线
    self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
 
    // 获取+按钮
    UIBarButtonItem *add = self.navigationItem.rightBarButtonItem;
    
    
    // 添加一个垃圾桶按钮
    UIBarButtonItem *trash = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemTrash target:self action:@selector(delete)];
    
    self.navigationItem.rightBarButtonItems = @[add,trash];
    
}

- (void)delete
{
//    self.tableView.editing = !self.tableView.editing;
    [self.tableView setEditing:!self.tableView.editing animated:YES];
    NSLog(@"delete");
}

// 懒加载数组
- (NSMutableArray *)contacts
{
    if (_contacts == nil) {
        _contacts = [NSKeyedUnarchiver unarchiveObjectWithFile:HMFilePath];
        
        if (_contacts == nil) { // 如果没有从文件中读取,需要自己手动创建
            _contacts = [NSMutableArray array];
            
        }
    }
    return _contacts;
}


#warning 第五步操作
#pragma mark - 注销功能
// 点击注销就会调用这个方法
- (IBAction)logout:(id)sender {
    
    UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:@"是否注销?" delegate:self cancelButtonTitle:@"取消" destructiveButtonTitle:@"注销" otherButtonTitles:nil, nil];
    
    
    [sheet showInView:self.view];
    
    
}
// 点击actionSheet上面的按钮会调用
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if (buttonIndex) return;
    
    // 回到登录界面
    [self.navigationController popViewControllerAnimated:YES];
}



/**
 *   跳转之前,调用这个方法
 */
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    NSLog(@"%@",segue.destinationViewController);
    
    
    if ([segue.destinationViewController isKindOfClass:[HMAddViewController class]]) {
        
        HMAddViewController *vc = segue.destinationViewController;
        
        vc.delegate = self;
    }else{ // 跳转到编辑控制器
        HMEditViewController *edit = segue.destinationViewController;
        
        // 获取选中cell的IndexPath
        NSIndexPath *seletedIndex = [self.tableView indexPathForSelectedRow];
        
        edit.delegate = self;
        edit.contact = self.contacts[seletedIndex.row];
        
    }
    
}

#pragma mark - 控制器代理方法
// 成功更新了一个联系人的时候调用
- (void)editViewController:(HMEditViewController *)edit didUpdateContact:(HMContact *)contact
{
    
    // 刷新表格
//    [self.tableView reloadData];
    
    // 局部刷新
    // 获取选中cell的IndexPath
    NSIndexPath *seletedIndex = [self.tableView indexPathForSelectedRow];
    [self.tableView reloadRowsAtIndexPaths:@[seletedIndex] withRowAnimation:UITableViewRowAnimationLeft];
    
    // 归档
    [NSKeyedArchiver archiveRootObject:self.contacts toFile:HMFilePath];
}

// 成功添加了一个联系人的时候调用
- (void)addViewController:(HMAddViewController *)add didAddContact:(HMContact *)contact
{
    // 保存
    [self.contacts addObject:contact];
    
    // 刷新表格
    [self.tableView reloadData];
    
    // 归档
    [NSKeyedArchiver archiveRootObject:self.contacts toFile:HMFilePath];
}



#pragma mark - Table view data source


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.
    return self.contacts.count;
}


// 返回每一行cell的外观
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    
    // 1.创建对象
    HMContactCell *cell = [HMContactCell cellWithTableView:tableView];
    
    // 2.传递模型
    cell.contact = self.contacts[indexPath.row];
    
    return cell;
}


#pragma mark tableView代理方法
/**
    只要你实现了这个方法,就会实现一个滑动删除效果
 *  当你提交一个编辑操作的时候就会调用
 *
 *  @param editingStyle 编辑样式
 *  @param indexPath    操作那一行的indexPath
 */
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    
    if (editingStyle == UITableViewCellEditingStyleDelete) { // 点击了删除
        
        // 更新数据
        [self.contacts removeObjectAtIndex:indexPath.row];
        
        // 局部删除有个条件 tableView里的cell总数必须和模型总数保持一致
        [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationLeft];
        
    }else{ // 点击添加按钮
        
        // 新建模型
        HMContact *contact = [HMContact contactWithName:@"grace" phone:@"123"];
        
        // 更新模型
//        [self.contacts addObject:contact];
        [self.contacts insertObject:contact atIndex:indexPath.row + 1];
        
        // 刷新界面
//        [self.tableView reloadData];
        
        NSIndexPath *nextIndexPath = [NSIndexPath indexPathForRow:indexPath.row + 1 inSection:0];
        [self.tableView insertRowsAtIndexPaths:@[nextIndexPath] withRowAnimation:UITableViewRowAnimationLeft];
        
        
    }
    
    // 归档
    [NSKeyedArchiver archiveRootObject:self.contacts toFile:HMFilePath];

}


/**
 *   当tableView进入编辑模式之前,就会调用
 *   返回每一行cell的编辑样式
 *
 */
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.row == 0) return UITableViewCellEditingStyleInsert;
    
    return UITableViewCellEditingStyleDelete;
}



@end


******登陆界面的 数据存储,偏好设置

#import "HMLoginViewController.h"

#import "MBProgressHUD+MJ.h"

#import "HMContactsTableViewController.h"

#define HMAccountKey @"account"
#define HMPwdKey @"pwd"
#define HMRmbPwdKey @"rmbPwd"
#define HMAutoLoginKey @"auto_login"

#define HMUserDefaults [NSUserDefaults standardUserDefaults]

@interface HMLoginViewController ()<UITextFieldDelegate>
@property (weak, nonatomic) IBOutlet UITextField *accountField;
@property (weak, nonatomic) IBOutlet UITextField *pwdField;
@property (weak, nonatomic) IBOutlet UIButton *loginBtn;
@property (weak, nonatomic) IBOutlet UISwitch *autoLoginS;
@property (weak, nonatomic) IBOutlet UISwitch *rmbPwdS;

@property (nonatomic, strong) HMContactsTableViewController *contact;

@end

@implementation HMLoginViewController


#warning 第四步做跳转之前的准备工作
/**
 *  执行segue的时候,跳转之前调用
 *  一般用做一些跳转之前的准备操作,给下一个控制器传值
 *  @param segue  <#segue description#>
 *  @param sender <#sender description#>
 */
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    
//    NSLog(@"%@---%@--%@",segue.identifier,segue.sourceViewController,segue.destinationViewController);
    
    // 获取目的控制器
    UIViewController *v = segue.destinationViewController;
    
    // 给联系人导航条设置标题
    v.navigationItem.title = [NSString stringWithFormat:@"%@的联系人",_accountField.text];
    
}

#warning 第三步处理登录功能
// 当点击登录的时候调用
- (IBAction)login:(id)sender { // hm 123
    
    // 判断用户输入的账号和密码是否正确
    if ([_accountField.text isEqualToString:@"hm"] && [_pwdField.text isEqualToString:@"123"]) { // 账号和密码正确
        
        // 保存登录数据
        [HMUserDefaults setObject:_accountField.text forKey:HMAccountKey];
        [HMUserDefaults setObject:_pwdField.text forKey:HMPwdKey];
        [HMUserDefaults setBool:_rmbPwdS.isOn forKey:HMRmbPwdKey];
        [HMUserDefaults setBool:_autoLoginS.isOn forKey:HMAutoLoginKey];
        
        // 同步:当前内存中的数据和沙盒同步
        [HMUserDefaults synchronize];
        
        // 显示遮盖:只要做一些比较耗时的操作最好用遮盖
        [MBProgressHUD showMessage:@"正在登录中"];
        
        // GCD
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.25 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            
            // 移除遮盖
            [MBProgressHUD hideHUD];
            

            // 执行segue
            [self performSegueWithIdentifier:@"login2contact" sender:nil];
            
//            [self.view endEditing:YES];
//            [_accountField resignFirstResponder];
//            [_pwdField resignFirstResponder];
            
        });
        
        
        
    }else{ // 不正确
        
        
        // MBProgressHud:提示框
        [MBProgressHUD showError:@"账号或者密码错误"];
        
    }
    
    
}

- (void)viewWillAppear:(BOOL)animated
{
}
- (void)viewDidAppear:(BOOL)animated
{ 
    [self.view endEditing:YES];   //键盘
    
}


#warning 第二步 处理Switch
// 当记住密码状态改变的时候调用
- (IBAction)rmbPwdSwitch:(UISwitch *)sender {
    //
    if (sender.isOn == NO) {
        [_autoLoginS setOn:NO animated:YES];

    }
    
}
// 当自动登录状态改变的时候调用
- (IBAction)autoLoginSwitch:(UISwitch *)sender {
    if (sender.isOn == YES) {
        [_rmbPwdS setOn:YES animated:YES];
    }

}


- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
#warning 第一步监听两个文本框的内容,控制器登录按钮的状态
    // 1.addTarget
    [_accountField addTarget:self action:@selector(textChange) forControlEvents:UIControlEventEditingChanged];
            [_pwdField addTarget:self action:@selector(textChange) forControlEvents:UIControlEventEditingChanged];
    
    
    // 从沙盒里面读取数据
    _accountField.text = [HMUserDefaults objectForKey:HMAccountKey];
    _rmbPwdS.on = [HMUserDefaults boolForKey:HMRmbPwdKey];
    if (_rmbPwdS.on) { // 记住密码才需要给密码文本框赋值
        _pwdField.text = [HMUserDefaults objectForKey:HMPwdKey];
        
    }
    _autoLoginS.on = [HMUserDefaults boolForKey:HMAutoLoginKey];
    if (_autoLoginS.on) { // 如果勾选了自动登录
        [self login:nil];
    }
    
    
    
    // 手动判断按钮是否能点击
    [self textChange];
    
    
}
// 当文本框的内容改变的时候就会调用
- (void)textChange
{
    // 判断两个文本框的内容
    _loginBtn.enabled = _accountField.text.length && _pwdField.text.length;
    

}

@end

 

posted @ 2015-08-27 15:56  iso  阅读(293)  评论(0编辑  收藏  举报