第三十三篇:私人通迅录(有存储功能)
来源:互联网 发布:阿里云服务器网络异常 编辑:程序博客网 时间:2024/06/09 15:32
用了第三方框架: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
2 0
- 第三十三篇:私人通迅录(有存储功能)
- 私人通讯录功能详细实现
- 第三十三篇:JAVA中的反射机制
- 第三十三篇:JAVA执行javascript方法
- 私人
- 外储说左下第三十三
- 第三十三章 目的
- 第三十三套
- 《道德经》第三十三章
- Outlook Express私人信件管理功能
- 第三十三篇·构建个人的服务器
- 通过Openstack + novadocker创建有存储功能的docker
- 第三十三 Hashtable和HashMap
- 写下第三十三封情书
- 第三十三章:木块砌墙
- 第三章 第四十三题
- 4.0 第三十三章 XML
- 第三本 十三章上机
- DIV CSS简介
- LRU算法
- 杭电ACM2017-字符串统计
- 直角三角形
- 软件开发流程
- 第三十三篇:私人通迅录(有存储功能)
- 并查集学习笔记
- set头文件使用方法
- stack,queue头文件使用方法
- 滚动数组
- vim的四种模式
- android下数据库操作
- 12 Highly divisible triangular number - Project Euler
- mybatis(5)输出映射