【案列】私人通讯录01
来源:互联网 发布:淘宝怎样发布宝贝 编辑:程序博客网 时间:2024/06/09 19:06
1.登录界面
//// ViewController.m#import "ViewController.h"#import "MBProgressHUD+MJ.h"@interface ViewController () <UITextFieldDelegate>@property (weak, nonatomic) IBOutlet UITextField *accountField;@property (weak, nonatomic) IBOutlet UITextField *pwdField;@property (weak, nonatomic) IBOutlet UIButton *loginBtn;@property (weak, nonatomic) IBOutlet UISwitch *rmbPwdSwitch;@property (weak, nonatomic) IBOutlet UISwitch *autoLoginSwitch;@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; // 给文本框添加监听 [self.accountField addTarget:self action:@selector(textChange) forControlEvents:UIControlEventEditingChanged]; [self.pwdField addTarget:self action:@selector(textChange) forControlEvents:UIControlEventEditingChanged]; // 判断登录按钮是否可以点击 [self textChange];}/** * segue跳转之前调用 */- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{ // 传值给目标控制器 UIViewController *vc = segue.destinationViewController; vc.title = [NSString stringWithFormat:@"%@的联系人",self.accountField.text];}/** * 登录操作 */- (IBAction)loginBtnAction:(UIButton *)sender{ // 添加蒙版 [MBProgressHUD showMessage:@"正在登录..."]; // 模拟请求网络 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ // 隐藏蒙版 [MBProgressHUD hideHUD]; // 验证帐号密码 if ([self.accountField.text isEqualToString:@"name"] && [self.pwdField.text isEqualToString:@"123"]) { // 跳转到联系人界面 [self performSegueWithIdentifier:@"login2contact" sender:nil]; }else{ // 帐号或者密码错误 [MBProgressHUD showError:@"帐号或者密码错误"]; } });}/** * 记住密码开关状态改变的时候调用 */- (IBAction)rmbPwdChnage:(UISwitch *)sender{ // 如果取消记住密码,自动登录也需要取消选中 if (self.rmbPwdSwitch.on == NO) { [self.autoLoginSwitch setOn:NO animated:YES]; }}/** * 自动登录开关状态改变的时候调用 */- (IBAction)autoLoginChnage:(UISwitch *)sender{ // 如果选中了自动登录,那么记住密码也要选中 if (self.autoLoginSwitch.on == YES) { [self.rmbPwdSwitch setOn:YES animated:YES]; }}/** * 文本框内容改变了 */- (void)textChange{ self.loginBtn.enabled = self.accountField.text.length && self.pwdField.text.length;}@end2.联系人
注意联系人界面是从登录界面控制器segue过来的,并不是从『登录按钮』直接segue过来的
//// ContactViewController.m#import "ContactViewController.h"#import "AddViewController.h"#import "Contact.h"#import "EditViewController.h"@interface ContactViewController ()<AddViewControllerDelegate>/** * 保存Contact模型对象的数组 */@property(nonatomic,strong)NSMutableArray *contacts;@end@implementation ContactViewController- (NSMutableArray *)contacts{ if (_contacts == nil) { _contacts = [NSMutableArray array]; } return _contacts;}- (void)viewDidLoad { [super viewDidLoad]; // 取消分割线// self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; // tableView有数据的时候才需要分割线 self.tableView.tableFooterView = [[UIView alloc] init];}/** * segue跳转之前会调用 */- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{ // 给添加控制器传递联系人控制器属性 AddViewController *addVC = segue.destinationViewController; addVC.delegate = self;}#pragma mark - AddViewControllerDelegate- (void)addViewController:(AddViewController *)addVC didClickAddBtnWithContact:(Contact *)contact{ // 把联系人模型保存到数组里面 [self.contacts addObject:contact]; // 刷新表格 [self.tableView reloadData];}/** * 点击注销的时候会调用 */- (IBAction)logout:(UIBarButtonItem *)sender{ // alert控制器 UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"是否要注销" message:nil preferredStyle:UIAlertControllerStyleActionSheet]; [alert addAction:[UIAlertAction actionWithTitle:@"注销" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) { // 注销 [self.navigationController popViewControllerAnimated:YES]; }]]; [alert addAction:[UIAlertAction actionWithTitle:@"不" style:UIAlertActionStyleCancel handler:nil]]; // 弹出 [self presentViewController:alert animated:YES completion:nil];}#pragma mark - Table view data source- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ return self.contacts.count;}- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ // 创建cell static NSString *ID = @"cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:ID]; } // 配置cell Contact *c = self.contacts[indexPath.row]; cell.textLabel.text = c.name; cell.detailTextLabel.text = c.phone; return cell;}#pragma mark - tabviewdelegate/** * 点击cell的时候调用 */- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ // 加载stroryborad(我们这里从storyboard创建控制器) UIStoryboard *sb = [UIStoryboard storyboardWithName:@"Main" bundle:nil]; // 创建编辑控制器 // "edit"标识符 在Main.storyboard EditViewController *edit = [sb instantiateViewControllerWithIdentifier:@"edit"]; edit.contact = self.contacts[indexPath.row]; // 设置block 要执行的 edit.block = ^(Contact *contact){ [self.contacts replaceObjectAtIndex:indexPath.row withObject:contact]; // 刷新表格 [self.tableView reloadData]; }; // 跳转到编辑界面 [self.navigationController pushViewController:edit animated:YES];}@end联系人模型:
//// Contact.h#import <Foundation/Foundation.h>@interface Contact : NSObject@property(nonatomic,strong)NSString *name;@property(nonatomic,strong)NSString *phone;/** * 快速返回一个联系人模型对象 */+ (instancetype)contactWithName:(NSString *)name phone:(NSString *)phone;@end
//// Contact.m#import "Contact.h"@implementation Contact+ (instancetype)contactWithName:(NSString *)name phone:(NSString *)phone{ Contact *c = [[self alloc] init]; c.name = name; c.phone = phone; return c;}@end3.添加联系人
//// AddViewController.h#import <UIKit/UIKit.h>// 代理@class AddViewController,Contact;@protocol AddViewControllerDelegate <NSObject>@optional- (void)addViewController:(AddViewController *)addVC didClickAddBtnWithContact:(Contact *)contact;@end@interface AddViewController : UIViewController// 代理属性@property(nonatomic,weak) id<AddViewControllerDelegate> delegate;@end
//// AddViewController.m#import "AddViewController.h"#import "Contact.h"#import "ContactViewController.h"@interface AddViewController ()@property (weak, nonatomic) IBOutlet UITextField *nameField;@property (weak, nonatomic) IBOutlet UITextField *phoneField;@property (weak, nonatomic) IBOutlet UIButton *addBtn;@end@implementation AddViewController- (IBAction)addBtnAction:(UIButton *)sender{ // 1.把姓名和电话包装成Contact模型对象 Contact *c = [Contact contactWithName:self.nameField.text phone:self.phoneField.text]; // 2.通知代理 if ([self.delegate respondsToSelector:@selector(addViewController:didClickAddBtnWithContact:)]) { [self.delegate addViewController:self didClickAddBtnWithContact:c]; } // 3.跳转回 联系人控制器 [self.navigationController popViewControllerAnimated:YES];}- (void)viewDidLoad { [super viewDidLoad]; // 给文本框添加监听 [self.nameField addTarget:self action:@selector(textChange) forControlEvents:UIControlEventEditingChanged]; [self.phoneField addTarget:self action:@selector(textChange) forControlEvents:UIControlEventEditingChanged];}- (void)viewDidAppear:(BOOL)animated{ // 姓名文本框成为第一响应者(会弹出键盘) [self.nameField becomeFirstResponder];}/** * 文本框内容改变了 */- (void)textChange{ self.addBtn.enabled = self.nameField.text.length && self.phoneField.text.length;}@end3.编辑联系人
编辑完成需要讲新的联系人数据传递给联系人控制器,我们这里没有想 添加联系人控制器一下使用代理,而是换了一种方法block。2种方法都可以实现。
(注意我们编辑界面也在storyboard里,设置了标识符"edit")
//// EditViewController.h#import <UIKit/UIKit.h>@class Contact;// 定义blocktypedef void(^EditViewControllerBlock)(Contact *contact);@interface EditViewController : UIViewController// block属性@property(nonatomic,strong) EditViewControllerBlock block;/** * 联系人模型对象 */@property(nonatomic,strong) Contact *contact;@end
//// EditViewController.m#import "EditViewController.h"#import "Contact.h"@interface EditViewController ()@property (weak, nonatomic) IBOutlet UITextField *nameField;@property (weak, nonatomic) IBOutlet UITextField *phoneField;@property (weak, nonatomic) IBOutlet UIButton *saveBtn;@end@implementation EditViewController- (void)setContact:(Contact *)contact{ _contact = contact;}/** * 保存操作 */- (IBAction)saveBtnAction:(UIButton *)sender{ // 把文本框的值包装成联系人模型 Contact *c = [Contact contactWithName:self.nameField.text phone:self.phoneField.text]; // 通知联系人控制修改了模型数据,刷新表格#warning 可以用代理和block,我们这里用block实现 if (self.block) { self.block(c); //调用block } // 返回联系人控制器 [self.navigationController popViewControllerAnimated:YES];}- (void)viewDidLoad { [super viewDidLoad]; // 设置导航条的标题 self.title = @"查看/编辑"; // 设置导航条右边的按钮 self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"编辑" style:UIBarButtonItemStyleDone target:self action:@selector(edit:)]; // 给文本框设置值 self.phoneField.text = self.contact.phone; self.nameField.text = self.contact.name; // 给文本框添加监听 [self.nameField addTarget:self action:@selector(textChange) forControlEvents:UIControlEventEditingChanged]; [self.phoneField addTarget:self action:@selector(textChange) forControlEvents:UIControlEventEditingChanged];}/** * 文本框内容改变了 */- (void)textChange{ self.saveBtn.enabled = self.nameField.text.length && self.phoneField.text.length;}/** * 点击了"编辑" */- (void)edit:(UIBarButtonItem *)item{ if ([item.title isEqualToString:@"编辑"]) { // 更改右上角按钮标题 item.title = @"取消"; self.phoneField.enabled = YES; self.nameField.enabled = YES; // 弹出电话文本框的内容 [self.phoneField becomeFirstResponder]; // 显示"保存"按钮 self.saveBtn.hidden = NO; }else if ([item.title isEqualToString:@"取消"]){ item.title = @"编辑"; self.phoneField.enabled = NO; self.nameField.enabled = NO; self.saveBtn.hidden = YES; // 还原数据 self.nameField.text = self.contact.name; self.phoneField.text = self.contact.phone; // 不允许编辑 键盘会自动隐藏// [self.view endEditing:YES]; }}/*#pragma mark - Navigation// In a storyboard-based application, you will often want to do a little preparation before navigation- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { // Get the new view controller using [segue destinationViewController]. // Pass the selected object to the new view controller.}*/@end
0 0
- 【案列】私人通讯录01
- 【案列】私人通讯录02 - 数据存储和删除
- 私人通讯录
- 私人通讯录
- 私人通讯录思路
- iOS私人通讯录
- No4 私人通讯录
- 小结:私人通讯录
- 小结:私人通讯录知识点
- 私人通讯录Demo - iOS
- 私人通讯录功能详细实现
- UINavigationController实例之私人通讯录
- 自建项目分享-私人通讯录
- iOS开发 - 私人通讯录实例
- 私人通讯录中遇到的注意点
- 练习:私人通讯录(整理思路)
- ui进阶第三天,私人通讯录的创建(元宵节快乐)
- 练习:私人通讯录(界面和功能展示)
- iOS基础之沙盒机制-路径获取
- 深刻理解Python中的元类(metaclass)
- 自然数幂和模板
- 数组和逗号表达式
- 字符指针的初始化以及程序分析实例
- 【案列】私人通讯录01
- 简单脱壳教程笔记(3)---手脱UPX壳(2)
- “1”+ “1”等于几?
- 蓝桥杯 第五届 六角填数
- 一个简易的账号登录/广播的使用
- 十二.通过bootstrap的modal.js来完成删除功能
- 安卓 jni 开发 —— Android Studio 打包 so 的坑
- [扫描线 线段树 暴力] BZOJ 4059 [Cerc2012]Non-boring sequences
- 最全面的linux信号量解析