*****联系人的界面的优化 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:@""]; // 更新模型
// [self.contacts addObject:contact];
[self.contacts insertObject:contact atIndex:indexPath.row + ]; // 刷新界面
// [self.tableView reloadData]; NSIndexPath *nextIndexPath = [NSIndexPath indexPathForRow:indexPath.row + inSection:];
[self.tableView insertRowsAtIndexPaths:@[nextIndexPath] withRowAnimation:UITableViewRowAnimationLeft]; } // 归档
[NSKeyedArchiver archiveRootObject:self.contacts toFile:HMFilePath]; } /**
* 当tableView进入编辑模式之前,就会调用
* 返回每一行cell的编辑样式
*
*/
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == ) 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:@""]) { // 账号和密码正确 // 保存登录数据
[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

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

  1. IOS第13天(1,私人通讯录,登陆功能,界面的跳转传值,自定义cell,编辑界面)

    ******HMLoginViewController 登陆的界面 #import "HMLoginViewController.h" #import "MBProgre ...

  2. IOS第13天(2,私人通讯录,plist存储,偏好设置,归档)

    ***************plist存储 // 当点点击保存的时候调用 //保存 - (IBAction)save:(id)sender { // 获取沙盒的根路径 // NSString *ho ...

  3. 2016-1-7第一个完整APP 私人通讯录的实现 5:保存数据

    一:登陆界面 1):用户点击登陆按钮并成功登陆后,根据此时的开关情况选择是否保存数据,代码如下: "]) { [self performSegueWithIdentifier:@" ...

  4. (三十八)从私人通讯录引出的细节II -数据逆传 -tableView点击 -自定义分割线

    项目中的警告是不会影响app发布的,例如引入第三方类库很容易引入警告. 细节1:跳转的数据传递. prepareForSegue: sender: 方法是在执行segue后,跳转之前调用这个方法,一般 ...

  5. IOS第七天(6:UiTableView编辑模式, 拖动位置 ,滑动删除)

    **********UiTableView编辑模式, 拖动位置 ,滑动删除 #import "HMViewController.h" @interface HMViewContro ...

  6. iOS UIKit:TableView之编辑模式(3)

    一般table view有编辑模式和正常模式,当table view进入编辑模式时,会在row的左边显示编辑和重排控件,如图 42所示的编辑模式时的控件布局:左边的editing control有表 ...

  7. iOS全埋点解决方案-数据存储

    前言 ​ SDK 需要把事件数据缓冲到本地,待符合一定策略再去同步数据. 一.数据存储策略 ​ 在 iOS 应用程序中,从 "数据缓冲在哪里" 这个纬度看,缓冲一般分两种类型. 内 ...

  8. iOS中的数据存储

    SQLite3 SQLite3是一款开源的嵌入式关系型数据库,可移植性好,易使用,内存开销小. SQLite3是无类型的,意味着你可以保存任何类型的数据到任意表的任意字段中. SQLite3常用的4种 ...

  9. IOS的四种数据存储方式及优劣

    IOS有四种经常使用数据存储方式: 第一种方法:用NSUserDefaults存储配置信息 NSUserDefaults被设计用来存储设备和应用的配置信息.它通过一个工厂方法返回默认的.也是最经常使用 ...

随机推荐

  1. BZOJ 3542 [Poi2014]Couriers ——可持久化线段树

    [题目分析] 查找区间内出现次数大于一半的数字. 直接用主席树,线段树上维护区间大小,由于要求出现次数大于一半,每到一个节点可以分治下去. 时间复杂度(N+Q)logN [代码] #include & ...

  2. 20145223《Java程序程序设计》第8周学习总结

    20145223 <Java程序设计>第8周学习总结 教材学习内容总结 第十四章 NIO与NIO2 ·NIO使用频道(Channel)来衔接数据节点,在处理数据时,NIO可以让你设定缓冲区 ...

  3. 内核终端判断,微信?QQ?ipad?IE?移动?Google?opera……

    $(document).ready(function(){ //判断访问终端 var browser={ versions:function(){ var u = navigator.userAgen ...

  4. STL UVA 11995 I Can Guess the Data Structure!

    题目传送门 题意:训练指南P186 分析:主要为了熟悉STL中的stack,queue,priority_queue,尤其是优先队列从小到大的写法 #include <bits/stdc++.h ...

  5. JSON字符串和对象之间的转换

    JSON(JavaScript Object Notation) 是JavaScript编程语言的一个子集.正因JSON是JavaScript的一个子集,所以它可清晰的运用于此语言中. eval函数 ...

  6. ps去水印

    使用仿制图章工具去除使用仿制图章工具去除文字这是比较常用的方法,具体的操作是,选取仿制图章工具,按住Alt键,在无文字区域点击相似的色彩名图案采样,然后在文字区域拖动鼠标复制以覆盖文字.要注意的是,采 ...

  7. LightOJ1298 One Theorem, One Year(DP + 欧拉函数性质)

    题目 Source http://www.lightoj.com/volume_showproblem.php?problem=1298 Description A number is Almost- ...

  8. myeclipse下拷贝的项目,tomcat下部署名称和导出为war包的名称默认值修改

    拷贝一个项目,作为一个新的项目,给它换了名字,这时候默认的部署名称等都是原来项目的,这时候要在属性里面修改一下.

  9. BZOJ 3170 & 切比雪夫距离

    题意: 给出N个点,在这N个点中选一个点使其它的点与这个点的切比雪夫距离和最小. SOL: TJOI真是...厚道还是防水...这种题目如果知道切比雪夫距离是什么那不就是傻逼题...如果不知道那不就懵 ...

  10. 20145304 刘钦令 Java程序设计第一周学习总结

    20145304<Java程序设计>第1周学习总结 教材学习内容总结 1995年5月23日,是公认的Java的诞生日,Java正式由Oak改名为Java. Java的三大平台是:Java ...