1.快捷添加rootViewController和navigateController
默认Main.storyboard中点选view图标,菜单Editor–Embed in–NavigateController了,将直接将rootViewController和navigateController一同创建
2.文本框的代理监听
界面:
指定控制器为LoginViewController类
LoginViewController.m
#import "LoginViewController.h"
@interface LoginViewController ()<UITextFieldDelegate>
@property (weak, nonatomic) IBOutlet UITextField *usernameField;
@property (weak, nonatomic) IBOutlet UITextField *passwordField;
@property (weak, nonatomic) IBOutlet UIButton *loginButton;
@end
@implementation LoginViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.usernameField.delegate=self;
}
//点击的时候会调用一次
/*
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
NSLog(@"%@",self.usernameField.text);
return YES;
}
*/
//文本框已经开始编辑
/*
- (void)textFieldDidBeginEditing:(UITextField *)textField{
NSLog(@"%@",self.usernameField.text);
}
//是否允许这个文本框结束编辑
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField{
return NO;
}
*/
//文本框结束编辑
- (void)textFieldDidEndEditing:(UITextField *)textField{
NSLog(@"文本框已经结束编辑");
}
//是否允许文本框改变文字内容,非实时监听文本改变
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
NSLog(@"%@",self.usernameField.text);
return YES;//YES文本可以改变,NO文本不能改变
}
@end
直接是用addtarget方式监听,不使用代理
LoginViewController.m
#import "LoginViewController.h"
@interface LoginViewController ()
@property (weak, nonatomic) IBOutlet UITextField *usernameField;
@property (weak, nonatomic) IBOutlet UITextField *passwordField;
@property (weak, nonatomic) IBOutlet UIButton *loginButton;
@end
@implementation LoginViewController
- (void)viewDidLoad {
[super viewDidLoad];
//监听文本框
[self.usernameField addTarget:self action:@selector(textChange) forControlEvents:UIControlEventEditingChanged];
[self.passwordField addTarget:self action:@selector(textChange) forControlEvents:UIControlEventEditingChanged];
}
-(void)textChange{
//如果两个文本框都有内容
/*
if (self.usernameField.text.length>0&&self.passwordField.text.length>0) {
self.loginButton.enabled=YES;
}else{
//不都有值的时候,登录按钮不可用
self.loginButton.enabled=NO;
}
*/
//或直接使用
self.loginButton.enabled=self.usernameField.text.length>0&&self.passwordField.text.length>0;
}
@end
3.Segue的属性
segue是控制器之间的那根线
每个segue对象,都有三个属性
1、唯一标识符
@property(nonatomic,readonly)NSString* identifier;
2、来源控制器
@property(nonatomic,readonly)id sourceViewController;
3、目标控制器
@property(nonatomic,readonly)id destinationViewController;
segue分为量大类型
1、自动型:点击某个控件后,自动执行segue,自动完成界面跳转
直接拖拽按钮到下一个控制器中,选择show或push即可
2、手动型:需要通过写代码手动执行segue,才能完成界面跳转
恰当的时候,使用perform方法执行对应的segue
[self performSegueWithIdentifier:@“identifiername” sender:nil];
如果点击某个空间后,需要做一些判断,也就是说,满足一定条件后才跳转到下一个界面,建议使用手动型segue
#import "LoginViewController.h"
@interface LoginViewController ()
@property (weak, nonatomic) IBOutlet UITextField *usernameField;
@property (weak, nonatomic) IBOutlet UITextField *passwordField;
@property (weak, nonatomic) IBOutlet UIButton *loginButton;
@end
@implementation LoginViewController
- (void)viewDidLoad {
[super viewDidLoad];
//监听文本框
[self.usernameField addTarget:self action:@selector(textChange) forControlEvents:UIControlEventEditingChanged];
[self.passwordField addTarget:self action:@selector(textChange) forControlEvents:UIControlEventEditingChanged];
[self.loginButton addTarget:self action:@selector(login) forControlEvents:UIControlEventTouchUpInside];
}
-(void)login{
//用户名和密码都正确的情况下
if ([self.usernameField.text isEqualToString:@"1"] && [self.passwordField.text isEqualToString:@"1"]) {
[self performSegueWithIdentifier:@"login2contacts" sender:nil];
return;
}
}
-(void)textChange{
//如果两个文本框都有内容
self.loginButton.enabled=self.usernameField.text.length>0&&self.passwordField.text.length>0;
}
@end
4.延时登录
如果需要等待几秒钟在执行操作可以使用dispatch_after
#import "LoginViewController.h"
@interface LoginViewController ()
@property (weak, nonatomic) IBOutlet UITextField *usernameField;
@property (weak, nonatomic) IBOutlet UITextField *passwordField;
@property (weak, nonatomic) IBOutlet UIButton *loginButton;
@end
@implementation LoginViewController
- (void)viewDidLoad {
[super viewDidLoad];
//监听文本框
[self.usernameField addTarget:self action:@selector(textChange) forControlEvents:UIControlEventEditingChanged];
[self.passwordField addTarget:self action:@selector(textChange) forControlEvents:UIControlEventEditingChanged];
[self.loginButton addTarget:self action:@selector(login) forControlEvents:UIControlEventTouchUpInside];
}
-(void)login{
//延时执行,第二个参数延时的秒数
dispatch_after(dispatch_time( DISPATCH_TIME_NOW,(int64_t)( 3*NSEC_PER_SEC)), dispatch_get_main_queue(),^{
if ([self.usernameField.text isEqualToString:@"1"] && [self.passwordField.text isEqualToString:@"1"]) {
[self performSegueWithIdentifier:@"login2contacts" sender:nil];
}
});
}
-(void)textChange{
//如果两个文本框都有内容
self.loginButton.enabled=self.usernameField.text.length>0&&self.passwordField.text.length>0;
}
@end
5.注销
创建另外一个类,指定为内容控制器的类
ContactViewController.m
#import "ContactViewController.h"
@interface ContactViewController ()
@end
@implementation ContactViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 添加左上角注销的按钮
UIBarButtonItem* item=[[UIBarButtonItem alloc]initWithTitle:@"注销" style:UIBarButtonItemStylePlain target:self action:@selector(logout)];
self.navigationItem.leftBarButtonItem=item;
}
//登出方法.注销按钮的点击事件,弹出一个对话框
-(void)logout{
NSLog(@"注销按钮弹框");
//被放弃的方法,不能够正常显示
UIActionSheet* sheet=[[UIActionSheet alloc]initWithTitle:@"注销" delegate:nil cancelButtonTitle:@"取消按钮标题" destructiveButtonTitle:@"另一个选项标题" otherButtonTitles:nil, nil];
[sheet showInView:self.view];
}
@end
6.ViewController之间传值
performSegueWithIdentifier:sender:方法的完整执行过程:
[self performSegueWithIdentifier:@"login2contacts" sender:nil];
//这个self是来源控制器
1、根据identifier去storyboard中找到对应的线,新建UIStoryboardSegue对象。
- 设置segue对象的sourceViewController(来源控制器)
- 新建并设置Segue对象的destinationViewController(目标控制器)
2、调用sourcViewController下面的方法,做一些跳转前的准备工作并且传入创建好的Segue对象
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender;
这个sender是当初performSegueWithIdentifier:sender中传入的sender
3、调用Segue对象的-(void)perform方法开始执行界面跳转操作
- 去的sourViewController所在的UINavigationController
- 调用UINavigationController的push方法将desionationViewController压入栈中,完成跳转
具体到下面的代码中
1、先找目标控制器ContactViewController,拿到目标控制器对象
2、给目标控制器设置一个username的属性
3、将用户名控件上的文本赋值给目标控制器的username属性
4、在目标控制器的viewDid方法或合适的位置获取self.username属性的值即可完成值在viewController之间的传递。
LoginViewController.m
#import "LoginViewController.h"
#import "ContactViewController.h"
@interface LoginViewController ()
@property (weak, nonatomic) IBOutlet UITextField *usernameField;
@property (weak, nonatomic) IBOutlet UITextField *passwordField;
@property (weak, nonatomic) IBOutlet UIButton *loginButton;
@end
@implementation LoginViewController
- (void)viewDidLoad {
[super viewDidLoad];
//监听文本框
[self.usernameField addTarget:self action:@selector(textChange) forControlEvents:UIControlEventEditingChanged];
[self.passwordField addTarget:self action:@selector(textChange) forControlEvents:UIControlEventEditingChanged];
[self.loginButton addTarget:self action:@selector(login) forControlEvents:UIControlEventTouchUpInside];
}
-(void)login{
//使用第三方库
//[MBProgressHUD showMessage:@"正在登录"];
//[SVProgressHUD show];
//延时执行,第二个参数延时的秒数
dispatch_after(dispatch_time( DISPATCH_TIME_NOW,(int64_t)( 3*NSEC_PER_SEC)), dispatch_get_main_queue(),^{
if ([self.usernameField.text isEqualToString:@"1"] && [self.passwordField.text isEqualToString:@"1"]) {
[self performSegueWithIdentifier:@"login2contacts" sender:nil];
}
});
}
//-------------------------------------------------------------
//只要走storyboard线都会调用这个方法
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
//获取目标控制器
ContactViewController* contact= segue.destinationViewController;
//将控件上的文本赋值到目标控制器的username属性上
contact.username=self.usernameField.text;
}
//---------------------------------------------------------------
-(void)textChange{
//如果两个文本框都有内容
self.loginButton.enabled=self.usernameField.text.length>0&&self.passwordField.text.length>0;
}
@end
ContactViewController.h
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface ContactViewController : UITableViewController
//设置一个username属性,用来接收从根控制器传来的用户名
@property(nonatomic,copy) NSString* username;
@end
NS_ASSUME_NONNULL_END
ContactViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
// 添加左上角注销的按钮
UIBarButtonItem* item=[[UIBarButtonItem alloc]initWithTitle:@"注销" style:UIBarButtonItemStylePlain target:self action:@selector(logout)];
self.navigationItem.leftBarButtonItem=item;
//将来源控制器设定的username属性的值使用上
self.navigationItem.title=self.username;
}
//登出方法.注销按钮的点击事件,弹出一个对话框
-(void)logout{
NSLog(@"注销按钮弹框");
//被放弃的方法,不能够正常显示
UIActionSheet* sheet=[[UIActionSheet alloc]initWithTitle:@"注销" delegate:nil cancelButtonTitle:@"取消按钮标题" destructiveButtonTitle:@"另一个选项标题" otherButtonTitles:nil, nil];
[sheet showInView:self.view];
}
@end
7.ViewController之间逆传值–添加联系人
1、创建联系人模型Contract
Contract.h
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface Contract : NSObject
@property(nonatomic,copy)NSString* name;
@property(nonatomic,copy)NSString* number;
@end
NS_ASSUME_NONNULL_END
Contract.m
#import "Contract.h"
@implementation Contract
@end
2、创建联系人列表对应的ContractViewController
ContractViewController.h
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
//设置一个username属性,用来接收从根控制器传来的用户名
@interface ContactViewController : UITableViewController
@property(nonatomic,copy) NSString* username;
@end
NS_ASSUME_NONNULL_END
ContractViewController.m
#import "ContactViewController.h"
#import "AddViewController.h"
@interface ContactViewController ()<AddViewControllerDelegate>
@property(nonatomic,strong)NSMutableArray* contracts;
@end
@implementation ContactViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 添加左上角注销的按钮
UIBarButtonItem* item=[[UIBarButtonItem alloc]initWithTitle:@"注销" style:UIBarButtonItemStylePlain target:self action:@selector(logout)];
self.navigationItem.leftBarButtonItem=item;
//将来源控制器设定的username属性的值使用上
self.navigationItem.title=self.username;
}
#pragma mark -----懒加载数据-----
//懒加载contracts
//重写contracts的get方法
-(NSMutableArray*)contracts{
if (_contracts==nil) {
_contracts=[NSMutableArray array];
}
return _contracts;
}
//实现tableView的数据源方法
//返回一组有多少行
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return self.contracts.count;
}
//返回tableviewcell
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
//单元格重用id
static NSString* strId=@"contractCell";
//去缓存池找
UITableViewCell* cell= [tableView dequeueReusableCellWithIdentifier:strId];
//给单元格赋值
cell.textLabel.text=[self.contracts[indexPath.row] name] ;
cell.detailTextLabel.text=[self.contracts[indexPath.row] number];
return cell;
}
//-----------------------------------------------------------------------
//实现代理的方法(逆传)
-(void)addViewController:(AddViewController *)addViewController withmodel:(Contract *)contract{
//把模型数据传到contracts数组中
[self.contracts addObject:contract];
[self.tableView reloadData];
NSLog(@"%@----%@",contract.name,contract.number);
}
//获取segue的方法,只有走storyboard线,无论是自动型还是手动型都会调用
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
AddViewController* add=segue.destinationViewController;
add.delegate=self;
}
//-----------------------------------------------------------------------
//登出方法.注销按钮的点击事件,弹出一个对话框
-(void)logout{
NSLog(@"注销按钮弹框");
//被放弃的方法,不能够正常显示
UIActionSheet* sheet=[[UIActionSheet alloc]initWithTitle:@"注销" delegate:nil cancelButtonTitle:@"取消按钮标题" destructiveButtonTitle:@"另一个选项标题" otherButtonTitles:nil, nil];
[sheet showInView:self.view];
}
@end
3、创建新的viewController并制定AddViewController作为控制器类
AddViewController.h
#import <UIKit/UIKit.h>
#import "Contract.h"
@class AddViewController;
NS_ASSUME_NONNULL_BEGIN
@protocol AddViewControllerDelegate <NSObject>
@optional
-(void)addViewController:(AddViewController*)addViewController withmodel:(Contract *) contract;
@end
@interface AddViewController : UIViewController
@property(nonatomic,weak)id<AddViewControllerDelegate> delegate;
@end
NS_ASSUME_NONNULL_END
AddViewController.m
#import "AddViewController.h"
#import "Contract.h"
@interface AddViewController ()
@property (weak, nonatomic) IBOutlet UITextField *nameField;
@property (weak, nonatomic) IBOutlet UITextField *numberField;
@property (weak, nonatomic) IBOutlet UIButton *addButton;
@end
@implementation AddViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 监听两个文本框的内容变化
[self.nameField addTarget:self action:@selector(textChange) forControlEvents:UIControlEventEditingChanged];
[self.numberField addTarget:self action:@selector(textChange) forControlEvents:UIControlEventEditingChanged];
//监听添加按钮的点击事件
[self.addButton addTarget:self action:@selector(addClick) forControlEvents:UIControlEventTouchUpInside];
}
//添加按钮提交的方法
-(void)addClick{
//判断代理方法是否能够响应,
if ([self.delegate respondsToSelector:@selector(addViewController:withmodel:)]) {
//创建一个模型
Contract* contract=[[Contract alloc]init];
contract.name=self.nameField.text;
contract.number=self.numberField.text;
//如果可以响应,则执行代理方法
[self.delegate addViewController:self withmodel:contract];
}
//返回上一个控制器(联系人列表)
[self.navigationController popViewControllerAnimated:YES];
}
//文本变动时的方法
-(void)textChange{
self.addButton.enabled=self.nameField.text.length>0 && self.numberField.text>0;
}
@end
8.查看/编辑联系人
1、先从联系人列表里顺传值到–查看编辑联系人,因此需要在联系人列表里创建名字和号码属性。
2、创建EditingViewController类,并指导到新创建的控制器上
#import "EditViewController.h"
@interface EditViewController ()
- (IBAction)editClick:(UIBarButtonItem*)sender;
@property (weak, nonatomic) IBOutlet UITextField *nameField;
@property (weak, nonatomic) IBOutlet UITextField *numberField;
@property (weak, nonatomic) IBOutlet UIBarButtonItem *saveitemButton;
@property (weak, nonatomic) IBOutlet UIButton *saveButton;
@end
@implementation EditViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
//右上角编辑按钮点击事件
- (IBAction)editClick:(UIBarButtonItem*)sender {
if ([sender.title isEqualToString:@"编辑"]) {
sender.title=@"取消";
self.nameField.enabled=YES;
self.numberField.enabled=YES;
self.saveButton.hidden=NO;
}else{
sender.title=@"编辑";
self.nameField.enabled=NO;
self.numberField.enabled=NO;
self.saveButton.hidden=YES;
}
}
@end
9.编辑保存联系人
修改的EditViewController控制器
EditViewController.h
#import <UIKit/UIKit.h>
#import "Contract.h"
@class EditViewController;
NS_ASSUME_NONNULL_BEGIN
@protocol EditViewControllerDelegate<NSObject>
-(void)editViewController:(EditViewController *)editViewController withcontract:(Contract*)contract;
@end
@interface EditViewController : UIViewController
@property(nonatomic,strong)Contract* contact;
@property(nonatomic,weak)id<EditViewControllerDelegate> delegate;
@end
NS_ASSUME_NONNULL_END
EditViewController.m
#import "EditViewController.h"
@interface EditViewController ()
- (IBAction)editClick:(UIBarButtonItem*)sender;
@property (weak, nonatomic) IBOutlet UITextField *nameField;
@property (weak, nonatomic) IBOutlet UITextField *numberField;
@property (weak, nonatomic) IBOutlet UIBarButtonItem *saveitemButton;
@property (weak, nonatomic) IBOutlet UIButton *saveButton;
@end
@implementation EditViewController
- (void)viewDidLoad {
[super viewDidLoad];
//设置初始的文本框的内容(传过来的内容)
self.nameField.text=self.contact.name;
self.numberField.text=self.contact.number;
//监听保存按钮的点击事件
[self.saveButton addTarget:self action:@selector(saveButtonClick) forControlEvents:UIControlEventTouchUpInside];
}
//保存按钮被点击
-(void)saveButtonClick{
Contract* con=[[Contract alloc]init];//实际这个模型用不上
/*
con.name=self.nameField.text;
con.number=self.numberField.text;
*/
self.contact.name=self.nameField.text;
self.contact.number=self.numberField.text;
//判断代理方法是不是可以响应
if ([self.delegate respondsToSelector:@selector(editViewController:withcontract:)] ){
[self.delegate editViewController:self withcontract:con];
}
//返回到上一个页面
[self.navigationController popViewControllerAnimated:YES];
}
//右上角编辑按钮点击事件
- (IBAction)editClick:(UIBarButtonItem*)sender {
if ([sender.title isEqualToString:@"编辑"]) {//点击编辑
sender.title=@"取消";
self.nameField.enabled=YES;
self.numberField.enabled=YES;
self.saveButton.hidden=NO;
}else{
sender.title=@"编辑";//点击取消
self.nameField.enabled=NO;
self.numberField.enabled=NO;
self.saveButton.hidden=YES;
//恢复到从tableview中传过来的模型的数据
self.nameField.text=self.contact.name;
self.numberField.text=self.contact.number;
}
}
@end
AddViewController类
AddViewController.h
#import <UIKit/UIKit.h>
#import "Contract.h"
@class AddViewController;
NS_ASSUME_NONNULL_BEGIN
@protocol AddViewControllerDelegate <NSObject>
@optional
-(void)addViewController:(AddViewController*)addViewController withmodel:(Contract *) contract;
@end
@interface AddViewController : UIViewController
@property(nonatomic,weak)id<AddViewControllerDelegate> delegate;
@end
NS_ASSUME_NONNULL_END
AddViewController.m
#import "AddViewController.h"
#import "Contract.h"
@interface AddViewController ()
@property (weak, nonatomic) IBOutlet UITextField *nameField;
@property (weak, nonatomic) IBOutlet UITextField *numberField;
@property (weak, nonatomic) IBOutlet UIButton *addButton;
@end
@implementation AddViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 监听两个文本框的内容变化
[self.nameField addTarget:self action:@selector(textChange) forControlEvents:UIControlEventEditingChanged];
[self.numberField addTarget:self action:@selector(textChange) forControlEvents:UIControlEventEditingChanged];
//监听添加按钮的点击事件
[self.addButton addTarget:self action:@selector(addClick) forControlEvents:UIControlEventTouchUpInside];
}
//添加按钮提交的方法
-(void)addClick{
//判断代理方法是否能够响应,
if ([self.delegate respondsToSelector:@selector(addViewController:withmodel:)]) {
//创建一个模型
Contract* contract=[[Contract alloc]init];
contract.name=self.nameField.text;
contract.number=self.numberField.text;
//如果可以响应,则执行代理方法
[self.delegate addViewController:self withmodel:contract];
}
//返回上一个控制器(联系人列表)
[self.navigationController popViewControllerAnimated:YES];
}
//文本变动时的方法
-(void)textChange{
self.addButton.enabled=self.nameField.text.length>0 && self.numberField.text>0;
}
@end
ContactViewController类
ContactViewController.h
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
//设置一个username属性,用来接收从根控制器传来的用户名
@interface ContactViewController : UITableViewController
@property(nonatomic,copy) NSString* username;
@end
NS_ASSUME_NONNULL_END
ContactViewController.m
#import "ContactViewController.h"
#import "AddViewController.h"
#import "EditViewController.h"
@interface ContactViewController ()<AddViewControllerDelegate,EditViewControllerDelegate>
@property(nonatomic,strong)NSMutableArray* contracts;
@end
@implementation ContactViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 添加左上角注销的按钮
UIBarButtonItem* item=[[UIBarButtonItem alloc]initWithTitle:@"注销" style:UIBarButtonItemStylePlain target:self action:@selector(logout)];
self.navigationItem.leftBarButtonItem=item;
//将来源控制器设定的username属性的值使用上
self.navigationItem.title=self.username;
}
#pragma mark -----懒加载数据-----
//懒加载contracts
//重写contracts的get方法
-(NSMutableArray*)contracts{
if (_contracts==nil) {
_contracts=[NSMutableArray array];
}
return _contracts;
}
//实现tableView的数据源方法
//返回一组有多少行
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return self.contracts.count;
}
//返回tableviewcell
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
//单元格重用id
static NSString* strId=@"contractCell";
//去缓存池找
UITableViewCell* cell= [tableView dequeueReusableCellWithIdentifier:strId];
//给单元格赋值
cell.textLabel.text=[self.contracts[indexPath.row] name] ;
cell.detailTextLabel.text=[self.contracts[indexPath.row] number];
return cell;
}
//-----------------------------------------------------------------------
//实现添加联系人的代理方法(逆传)
-(void)addViewController:(AddViewController *)addViewController withmodel:(Contract *)contract{
//把模型数据传到contracts数组中
[self.contracts addObject:contract];
[self.tableView reloadData];
NSLog(@"%@----%@",contract.name,contract.number);
}
//编辑联系人的代理方法
-(void)editViewController:(EditViewController *)editViewController withcontract:(Contract *)contract{
[self.tableView reloadData];
//NSLog(@"%@",contract.number);
}
//获取segue的方法,只有走storyboard线,无论是自动型还是手动型都会调用
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
//先拿到一个viewcontroller
UIViewController* viewController=segue.destinationViewController;
//判断目标控制器的真实类型
if ([viewController isKindOfClass:[AddViewController class]]) {
//设置代理,需要强转一下
AddViewController* add=(AddViewController*)viewController;
add.delegate=self;
}else{
//顺传赋值
EditViewController* edit=(EditViewController*)viewController;
//设置代理
edit.delegate=self;
//获取点击cell的位置
NSIndexPath* path= [self.tableView indexPathForSelectedRow];
//获取模型
Contract* con=self.contracts[path.row];
edit.contact=con;
}
}
//-----------------------------------------------------------------------
//登出方法.注销按钮的点击事件,弹出一个对话框
-(void)logout{
NSLog(@"注销按钮弹框");
//被放弃的方法,不能够正常显示
UIActionSheet* sheet=[[UIActionSheet alloc]initWithTitle:@"注销" delegate:nil cancelButtonTitle:@"取消按钮标题" destructiveButtonTitle:@"另一个选项标题" otherButtonTitles:nil, nil];
[sheet showInView:self.view];
}
@end
结果:
10.开关处理
LoginViewController.m
//监听开关变化
- (IBAction)autoChangeClick:(UISwitch*)sender {
if (sender.isOn) {
//自动登录点开,则记住密码也点开
//self.remPassword.on=YES;
//用设置动画的形式打开
[self.remPassword setOn:YES animated:YES];
}
}
- (IBAction)remPasswordChange:(UISwitch*)sender {
if (!sender.isOn) {
//取消记住密码也不在进行自动登录
//self.autoLogin.on=NO;
[self.autoLogin setOn:NO animated:YES];
}
}
11.记住密码和自动登录
LoginViewController.m
#import "LoginViewController.h"
#import "ContactViewController.h"
#define kUsernameKey @"kUsernameKey"
#define kPasswrodKey @"kPasswordKey"
#define kremPasswordKey @"kRemPassworKey"
#define kAutolgoinKey @"kAutologinKey"
@interface LoginViewController ()
@property (weak, nonatomic) IBOutlet UITextField *usernameField;
@property (weak, nonatomic) IBOutlet UITextField *passwordField;
@property (weak, nonatomic) IBOutlet UIButton *loginButton;
@property (weak, nonatomic) IBOutlet UISwitch *remPassword;
@property (weak, nonatomic) IBOutlet UISwitch *autoLogin;
- (IBAction)remPasswordChange:(UISwitch*)sender;
- (IBAction)autoChangeClick:(UISwitch*)sender;
@end
@implementation LoginViewController
- (void)viewDidLoad {
[super viewDidLoad];
//监听文本框
[self.usernameField addTarget:self action:@selector(textChange) forControlEvents:UIControlEventEditingChanged];
[self.passwordField addTarget:self action:@selector(textChange) forControlEvents:UIControlEventEditingChanged];
//监听登录文本
[self.loginButton addTarget:self action:@selector(login) forControlEvents:UIControlEventTouchUpInside];
//恢复开关状态
NSUserDefaults* userdefaults=[NSUserDefaults standardUserDefaults];
self.remPassword.on=[userdefaults boolForKey:kremPasswordKey];
self.autoLogin.on=[userdefaults boolForKey:kAutolgoinKey];
//恢复用户名和密码
self.usernameField.text=[userdefaults objectForKey:kUsernameKey];
//如果记住密码打开
if (self.remPassword.isOn) {
//将密码从usrdefaults中取出
self.passwordField.text=[userdefaults objectForKey:kPasswrodKey];
}
//如果自动登录打开
if (self.autoLogin.isOn) {
[self login];//直接执行登录
}
[self textChange];
}
-(void)login{
//使用第三方库
//[MBProgressHUD showMessage:@"正在登录"];
//[SVProgressHUD show];
//延时执行,第二个参数延时的秒数
//当用户名和密码正确的时候,进行跳转
dispatch_after(dispatch_time( DISPATCH_TIME_NOW,(int64_t)( 3*NSEC_PER_SEC)), dispatch_get_main_queue(),^{
if ([self.usernameField.text isEqualToString:@"1"] && [self.passwordField.text isEqualToString:@"1"]) {
[self performSegueWithIdentifier:@"login2contacts" sender:nil];
//保存状态
NSUserDefaults* userdefaults=[NSUserDefaults standardUserDefaults];
//写入到nsuerdefaults对象
[userdefaults setBool:self.remPassword.isOn forKey:kremPasswordKey];//记住密码
[userdefaults setBool:self forKey:kAutolgoinKey];//自动登录
[userdefaults setObject:self.usernameField.text forKey:kUsernameKey];//用户名
[userdefaults setObject:self.passwordField.text forKey:kPasswrodKey];//密码
[userdefaults synchronize];//同步写入
}
});
}
//只要走storyboard线都会调用这个方法
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
//获取目标控制器
ContactViewController* contact= segue.destinationViewController;
//将控件上的文本赋值到目标控制器的username属性上
contact.username=self.usernameField.text;
}
-(void)textChange{
//如果两个文本框都有内容
self.loginButton.enabled=self.usernameField.text.length>0&&self.passwordField.text.length>0;
}
//监听开关变化
- (IBAction)autoChangeClick:(UISwitch*)sender {
if (sender.isOn) {
//自动登录点开,则记住密码也点开
//self.remPassword.on=YES;
//用设置动画的形式打开
[self.remPassword setOn:YES animated:YES];
}
}
- (IBAction)remPasswordChange:(UISwitch*)sender {
if (!sender.isOn) {
//取消记住密码也不在进行自动登录
//self.autoLogin.on=NO;
[self.autoLogin setOn:NO animated:YES];
}
}
@end
效果
12.保存联系人(使用归档/解档)及滑动删除
由于[NSKeyedArchiver archiveRootObject:self.contracts toFile:kfilePath]方法已经过时,单独使用时还不出现问题,但是放在整个程序中,会出现崩溃的现象,这一点确实有点令人崩溃。
//让tableview进入编辑模式,里面的内容是点击(类似于点击,滑动后点击上面的按钮)之后所执行的操作
滑动删除
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
//删除数组中的元素
//[self.contracts removeObject:self.contracts[indexPath.row]];
[self.contracts removeObjectAtIndex:indexPath.row];
//刷新数据
//[self.tableView reloadData];
//删除某一行
[self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationLeft];
}
完整案例再次,代码不是太完美,有些功能实现的并不是很好
代码点击链接
自己写的笔记代码