用了第三方框架:MBProgressHUD
Main.storyboard:
Model
// // QJContact.h // 13-私人通迅录 // // Created by 瞿杰 on 15/10/9. // Copyright © 2015年 itcast. All rights reserved. // #import <Foundation/Foundation.h> @interface QJContact : NSObject<NSCoding> @property (nonatomic , copy) NSString * name; @property (nonatomic , copy) NSString * phoneNumber; + (instancetype)contact; @end
// // QJContact.m // 13-私人通迅录 // // Created by 瞿杰 on 15/10/9. // Copyright © 2015年 itcast. All rights reserved. // #import "QJContact.h" @implementation QJContact + (instancetype)contact{ return [[self alloc] init]; } // 归档(编码) - (void)encodeWithCoder:(NSCoder *)aCoder{ [aCoder encodeObject:self.name forKey:@"name"]; [aCoder encodeObject:self.phoneNumber forKey:@"phoneNumber"]; } //恢复(解码) - (instancetype)initWithCoder:(NSCoder *)aDecoder{ self.name = [aDecoder decodeObjectForKey:@"name"]; self.phoneNumber = [aDecoder decodeObjectForKey:@"phoneNumber"]; return self; } @end
View
// // QJContactCell.h // 13-私人通迅录 // // Created by 瞿杰 on 15/10/9. // Copyright © 2015年 itcast. All rights reserved. // #import <Foundation/Foundation.h> #import <UIKit/UIKit.h> @class QJContact; @interface QJContactCell : UITableViewCell @property (nonatomic , strong)QJContact * contact; + (instancetype)contactCellWithTableView:(UITableView *)tabelView; @end
// // QJContactCell.m // 13-私人通迅录 // // Created by 瞿杰 on 15/10/9. // Copyright © 2015年 itcast. All rights reserved. // #import "QJContactCell.h" #import "QJContact.h" @interface QJContactCell () @property (nonatomic , weak)UIView * speradLine; @property (weak, nonatomic) IBOutlet UILabel *nameLabel; @property (weak, nonatomic) IBOutlet UILabel *phoneNumberLabel; @end @implementation QJContactCell + (instancetype)contactCellWithTableView:(UITableView *)tabelView{ static NSString * ID = @"contact"; /** * 先从缓存中跟据"contact"标识找可用的cell;如果没有再从storyboard/xib中找 */ return [tabelView dequeueReusableCellWithIdentifier:ID]; } - (void)setContact:(QJContact *)contact{ _contact = contact ; self.nameLabel.text = contact.name; self.phoneNumberLabel.text = contact.phoneNumber; } /** * 当cell从storyboard/xib中创建出cell后立刻调用该方法 */ - (void)awakeFromNib{ // self.accessoryType = UITableViewCellAccessoryDisclosureIndicator; UIView * speradLine = [[UIView alloc]init]; speradLine.backgroundColor = [UIColor grayColor]; speradLine.alpha = 0.7; [self.contentView addSubview:speradLine]; self.speradLine = speradLine; } - (void)layoutSubviews{ // NSLog(@"---layoutSubviews--"); CGFloat X = 0; CGFloat W = self.frame.size.width; CGFloat H = 1; CGFloat Y = self.frame.size.height - H; self.speradLine.frame = CGRectMake(X, Y, W, H); } @end
Contorller
登陆页面:
// // QJLoginViewController.h // 13-私人通迅录 // // Created by 瞿杰 on 15/10/9. // Copyright © 2015年 itcast. All rights reserved. // #import <UIKit/UIKit.h> @interface QJLoginViewController : UIViewController @end
// // QJLoginViewController.m // 13-私人通迅录 // // Created by 瞿杰 on 15/10/9. // Copyright © 2015年 itcast. All rights reserved. // #import "QJLoginViewController.h" #import "QJContactViewController.h" #import "MBProgressHUD+MJ.h" #define QJKeyUserName @"userName" #define QJKeyPassword @"password" #define QJKeyRemeberPassword @"remeberPassword" #define QJKeyAutoLogin @"autoLogin" @interface QJLoginViewController () @property (weak, nonatomic) IBOutlet UITextField *userNameTextField; @property (weak, nonatomic) IBOutlet UITextField *passwordTextField; @property (weak, nonatomic) IBOutlet UISwitch *remeberPasswordSwith; @property (weak, nonatomic) IBOutlet UISwitch *autoLoginSwitch; @property (weak, nonatomic) IBOutlet UIButton *loginBtn; @property (weak, nonatomic) IBOutlet UIView *activityView; - (void)customNavigationItem; - (IBAction)login; - (void)changeUserNameTextField; - (void)changePasswordTextField; - (IBAction)remeberPassword; - (IBAction)autoLogin; @end @implementation QJLoginViewController - (void)viewDidLoad { [super viewDidLoad]; // 创建并设置navigationItem的backBarButtonItem [self customNavigationItem]; // NSLog(@"%@",NSHomeDirectory()); // 添加消息通知 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changeUserNameTextField) name:UITextFieldTextDidChangeNotification object:self.userNameTextField]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changePasswordTextField) name:UITextFieldTextDidChangeNotification object:self.passwordTextField]; // 读取配置 [self readConfiguratStat]; } - (void)viewDidAppear:(BOOL)animated{ [super viewDidAppear:animated]; static BOOL isAuto = NO; if (isAuto == NO) { isAuto = YES ; if(self.autoLoginSwitch.on && self.userNameTextField.text.length && self.passwordTextField.text.length ){ [self login]; } } } - (void)dealloc{ [[NSNotificationCenter defaultCenter] removeObserver:self]; } - (void)readConfiguratStat{ NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults]; self.userNameTextField.text = [defaults objectForKey:QJKeyUserName]; self.remeberPasswordSwith.on = [defaults boolForKey:QJKeyRemeberPassword]; if (self.remeberPasswordSwith.on) { self.passwordTextField.text = [defaults objectForKey:QJKeyPassword]; } self.autoLoginSwitch.on = [defaults boolForKey:QJKeyAutoLogin]; } - (void)saveConfiguratStat{ NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults]; [defaults setObject:self.userNameTextField.text forKey:QJKeyUserName]; [defaults setObject:self.passwordTextField.text forKey:QJKeyPassword]; [defaults setBool:self.remeberPasswordSwith.isOn forKey:QJKeyRemeberPassword]; [defaults setBool:self.autoLoginSwitch.isOn forKey:QJKeyAutoLogin]; } /** 创建并设置navigationItem的backBarButtonItem */ - (void)customNavigationItem { UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithTitle:@"返回" style:UIBarButtonItemStyleDone target:nil action:nil]; self.navigationItem.backBarButtonItem = item; } /** 监听userNameTextField的text内容改变,只要改变就会调用 */ - (void)changeUserNameTextField{ if (self.userNameTextField.text) { self.loginBtn.enabled = (self.userNameTextField.text.length && self.passwordTextField.text.length ); } } /** 监听passwordTextField的text内容改变,只要改变就会调用 */ - (void)changePasswordTextField{ if (self.passwordTextField.text) { self.loginBtn.enabled = (self.userNameTextField.text.length && self.passwordTextField.text.length ); } } - (IBAction)remeberPassword { [self.autoLoginSwitch setOn:self.remeberPasswordSwith.on animated:YES]; } - (IBAction)autoLogin { [self.remeberPasswordSwith setOn:self.autoLoginSwitch.on animated:YES]; } /** 响应loginBtn点击 */ - (IBAction)login { [self.view endEditing:YES]; // UIAlertView * alertView = [UIAlertView alloc]; if (![self.userNameTextField.text isEqualToString:@"QJ"]) { // 账号:QJ // [alertView initWithTitle:nil message:@"你输入的账号不存在" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil]; // [alertView show]; [MBProgressHUD showError:@"你输入的账号不存在"]; return ; } if ( ![self.passwordTextField.text isEqualToString:@"123"]) { // 密码:123 // [alertView initWithTitle:nil message:@"你输入的密码错误" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil]; // [alertView show]; [MBProgressHUD showError:@"你输入的密码错误"]; return ; } [MBProgressHUD showMessage:@"正在加载,稍等..."]; // 存储配置 [self saveConfiguratStat]; // self.activityView.hidden = NO; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [MBProgressHUD hideHUD]; // self.activityView.hidden = YES; [self performSegueWithIdentifier:@"login" sender:nil]; }); } /** 当UISegue对象初始化完后,在跳转到下一个挖人制器之前,系统自动调用 */ - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{ QJContactViewController * distVC = segue.destinationViewController; distVC.title = [NSString stringWithFormat:@"%@的通迅录",self.userNameTextField.text]; } @end
// // QJContactViewController.h // 13-私人通迅录 // // Created by 瞿杰 on 15/10/9. // Copyright © 2015年 itcast. All rights reserved. // #import <UIKit/UIKit.h> @interface QJContactViewController : UITableViewController @end
// // QJContactViewController.m // 13-私人通迅录 // // Created by 瞿杰 on 15/10/9. // Copyright © 2015年 itcast. All rights reserved. // #import "QJContactViewController.h" #import "QJContact.h" #import "QJAddContactViewController.h" #import "QJContactCell.h" #import "QJEditViewController.h" // 数据存储的绝对路径 #define QJContactFilepath [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"contactList.data"] @interface QJContactViewController ()<UIActionSheetDelegate,QJAddContactViewControllerDelegate,QJEditViewControllerDelegate> @property (nonatomic , strong)NSMutableArray * contactList; - (IBAction)logout; @end @implementation QJContactViewController - (void)viewDidLoad { [super viewDidLoad]; UIBarButtonItem * item = [[UIBarButtonItem alloc]initWithTitle:@"反回" style:UIBarButtonItemStyleDone target:nil action:nil]; self.navigationItem.backBarButtonItem = item; // 设置分隔线的样式 self.tableView.separatorStyle = UITableViewCellAccessoryNone; // 取一个数据 // NSArray * array = ; // NSString * document = [array lastObject]; // NSString * filePath = [document stringByAppendingPathComponent:@"contactList.plist"]; // NSLog(@"%@",filePath); // NSString * docuent = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"]; // NSString * filePath = [docuent stringByAppendingPathComponent:@"contactList.plist"]; // 从filePath中取QJContact对象 //NSString * filePath = (NSString *)QJContactFilePath; } //- (void)viewWillAppear:(BOOL)animated{ // // // NSLog(@"%@",contact); //} - (NSMutableArray *)contactList{ if (_contactList == nil) { // 取数据,需要时加载 _contactList = [NSKeyedUnarchiver unarchiveObjectWithFile:QJContactFilepath]; if (nil == _contactList) { _contactList = [NSMutableArray array]; } } return _contactList; } #pragma mark - tableViewDataSource协议方法 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ return self.contactList.count ; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ // 创建一个cell QJContactCell * cell = [QJContactCell contactCellWithTableView:tableView]; // 设置cell数据内容 QJContact * contact = self.contactList[indexPath.row]; cell.contact = contact; // NSLog(@"---cellForRowAtIndexPath---"); return cell; } #pragma mark - tableViewDelegate协议方法 /** * 当cell向左滑动后,点击了“删除”或其他按妞时做一些事情 */ - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{ if (UITableViewCellEditingStyleDelete == editingStyle) { // 删除类型 // 删除一行 [self.contactList removeObjectAtIndex:indexPath.row]; [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationLeft]; // 数据归档 [NSKeyedArchiver archiveRootObject:self.contactList toFile:QJContactFilepath]; } } //-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ // NSLog(@"选中一行--------"); // QJAddContactViewController * addCVC = [[QJAddContactViewController alloc]init]; // addCVC.view.backgroundColor = [UIColor whiteColor]; // // 设置navigationItem // addCVC.navigationItem.title = @"查看联系人"; // UIBarButtonItem * edit = [[UIBarButtonItem alloc]initWithTitle:@"编辑" style:(UIBarButtonItemStyleDone) target:nil action:nil]; // addCVC.navigationItem.rightBarButtonItems = @[edit]; // // [self.navigationController pushViewController:addCVC animated:YES]; //} - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{ id destVC = segue.destinationViewController; if ([destVC isKindOfClass:[QJAddContactViewController class]]) { QJAddContactViewController * addCVC = destVC; addCVC.delegate = self; } else if([destVC isKindOfClass:[QJEditViewController class]]){ NSIndexPath * indexPath = [self.tableView indexPathForSelectedRow]; QJContact * contact = self.contactList[indexPath.row]; QJEditViewController * editVC = destVC; editVC.contact = contact ; editVC.delegate = self; } } /** 点击注消,响应事件 */ - (IBAction)logout { UIActionSheet * sheet = [[UIActionSheet alloc]initWithTitle:@"是否确定要注消" delegate:self cancelButtonTitle:@"取消" destructiveButtonTitle:@"确定" otherButtonTitles:nil, nil]; // 从底部升出一个弹窗 [sheet showInView:self.view]; } #pragma mark - UIActionSheet代理方法 - (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{ if (buttonIndex == 0) { [self.navigationController popViewControllerAnimated:YES]; } } #pragma mark - QJAddContactViewControllerDelegate - (void)addContactViewController:(QJAddContactViewController *)addCVC didClickAddBtnWithQJContact:(QJContact *)contact{ [self.contactList addObject:contact]; [self.tableView reloadData]; // 数据归档 [NSKeyedArchiver archiveRootObject:self.contactList toFile:QJContactFilepath]; } #pragma mark - QJEditViewControllerDelegate - (void)editViewController:(QJEditViewController *)editVC didSaveWithContact:(QJContact *)contact{ // 这里不用设置修改的contact,原因是:当时从当前控制器的某个contatct传到下一个QJEditViewController控制器的contact,地址是一样的,所以当QJEditViewController控制器的contact被修改了,当前控制器传入的contact也会修改。所以在这个方法体内不必理会当前传入的contact // 数据归档 [NSKeyedArchiver archiveRootObject:self.contactList toFile:QJContactFilepath]; [self.tableView reloadData]; } @end
// // QJAddContactViewController.h // 13-私人通迅录 // // Created by 瞿杰 on 15/10/9. // Copyright © 2015年 itcast. All rights reserved. // #import <UIKit/UIKit.h> @class QJContact,QJAddContactViewController; @protocol QJAddContactViewControllerDelegate <NSObject> - (void)addContactViewController:(QJAddContactViewController *) addCVC didClickAddBtnWithQJContact:(QJContact *)contact; @end @interface QJAddContactViewController : UIViewController @property (nonatomic , weak)id<QJAddContactViewControllerDelegate> delegate; @end
// // QJAddContactViewController.m // 13-私人通迅录 // // Created by 瞿杰 on 15/10/9. // Copyright © 2015年 itcast. All rights reserved. // #import "QJAddContactViewController.h" #import "QJContact.h" @interface QJAddContactViewController () @property (weak, nonatomic) IBOutlet UITextField *nameTextField; @property (weak, nonatomic) IBOutlet UITextField *phoneNumber; @property (weak, nonatomic) IBOutlet UIButton *addBtn; - (void)changeTextField; - (void)addContact; @end @implementation QJAddContactViewController - (void)viewDidLoad { [super viewDidLoad]; // self.title = @"添加联系人"; self.navigationItem.title = @"添加联系人"; // 成为第一响应 [self.nameTextField becomeFirstResponder ]; // 添加UITextFieldTextDidChangeNotification通知 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changeTextField) name:UITextFieldTextDidChangeNotification object:self.nameTextField]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changeTextField) name:UITextFieldTextDidChangeNotification object:self.phoneNumber]; // 添加addBtn按妞监听 [self.addBtn addTarget:self action:@selector(addContact) forControlEvents:UIControlEventTouchUpInside]; } - (void)dealloc{ // 有监听就要移除 [[NSNotificationCenter defaultCenter] removeObserver:self]; } - (void)changeTextField{ self.addBtn.enabled = (self.nameTextField.text.length > 0 && self.phoneNumber.text.length > 0); } - (void)addContact{ QJContact * contact = [QJContact contact]; contact.name = self.nameTextField.text; contact.phoneNumber = self.phoneNumber.text; // if ([self.delegate respondsToSelector:@selector(addContactViewController:didClickAddBtnWithQJContact:)]) { [self.delegate addContactViewController:self didClickAddBtnWithQJContact:contact]; } [self.navigationController popViewControllerAnimated:YES]; } @end
// // QJEditViewController.h // 13-私人通迅录 // // Created by 瞿杰 on 15/10/9. // Copyright © 2015年 itcast. All rights reserved. // #import <UIKit/UIKit.h> @class QJContact,QJEditViewController; @protocol QJEditViewControllerDelegate <NSObject> - (void)editViewController:(QJEditViewController *)editVC didSaveWithContact:(QJContact *)contact; @end @interface QJEditViewController : UIViewController @property (nonatomic , strong)QJContact * contact; @property (nonatomic , weak)id<QJEditViewControllerDelegate> delegate; @end
// // QJEditViewController.m // 13-私人通迅录 // // Created by 瞿杰 on 15/10/9. // Copyright © 2015年 itcast. All rights reserved. // #import "QJEditViewController.h" #import "QJContact.h" @interface QJEditViewController () @property (weak, nonatomic) IBOutlet UITextField *nameTextField; @property (weak, nonatomic) IBOutlet UITextField *phoneNumberTextField; @property (weak, nonatomic) IBOutlet UIButton *saveBtn; @property (weak, nonatomic) IBOutlet UIBarButtonItem *editBtn; - (IBAction)editBtnDidClicked:(id)sender; - (void)save:(UIButton *)btn; - (void)changeTextFieldContents; @end @implementation QJEditViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. // 填数据 self.nameTextField.text = self.contact.name; self.phoneNumberTextField.text = self.contact.phoneNumber; self.nameTextField.enabled = NO; self.phoneNumberTextField.enabled = NO; self.saveBtn.enabled = YES; self.saveBtn.hidden = YES; // 添加监听点击事件 [self.saveBtn addTarget:self action:@selector(save:) forControlEvents:(UIControlEventTouchUpInside)]; // 添加消息监听 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changeTextFieldContents) name:UITextFieldTextDidChangeNotification object:nil]; } - (void)dealloc{ // NSLog(@"----dealloc---"); [[NSNotificationCenter defaultCenter] removeObserver:self]; } /** * 时时监听textField内容的改变,以改变saveBtn能否交互状态 */ - (void)changeTextFieldContents{ self.saveBtn.enabled = (self.nameTextField.text.length > 0 && self.phoneNumberTextField.text.length > 0) ; } /** * 点击saveBtn时调用, */ - (void)save:(UIButton *)btn{ // 销毁 [self.navigationController popViewControllerAnimated:YES]; self.contact.name = self.nameTextField.text ; self.contact.phoneNumber = self.phoneNumberTextField.text; if ([self.delegate respondsToSelector:@selector(editViewController:didSaveWithContact:)]) { [self.delegate editViewController:self didSaveWithContact:self.contact]; } } - (IBAction)editBtnDidClicked:(id)sender { if ([self.editBtn.title isEqualToString:@"编辑"]) { self.editBtn.title = @"取消"; self.nameTextField.enabled = YES; self.phoneNumberTextField.enabled = YES; self.saveBtn.hidden = NO; [self.phoneNumberTextField becomeFirstResponder]; } else { self.editBtn.title = @"编辑"; [self.view endEditing:YES]; self.nameTextField.enabled = NO; self.phoneNumberTextField.enabled = NO; self.saveBtn.hidden = YES; self.nameTextField.text = self.contact.name; self.phoneNumberTextField.text = self.contact.phoneNumber; } } @end