1.通过storyboard添加的segue
我们都知道 segue完成界面的跳转是通过一个performSegueWithIdentifier函数 这个函数由当前的视图控制器调用
我们分析下performSegueWithIdentifier方法完整的执行过程
- 根据identifier去storyboard中找到对应的线,新建UIStoryboardSegue对象
- 设置Segue对象的sourceViewController(来源控制器)
- 新建并且设置Segue对象的destinationViewController(目标控制器)
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender;
//这个sender是当初perform seguewithidentifier:sender中传入的sender
3.调用segue对象的- (void)perform;方法执行界面跳转操作
3.1取得sourceViewController所在的NavigationController
3.2调用NavigationController的push方法将destinationViewController压入栈中 完成跳转
所以 在源控制器中 只要实现以下代码 就能修改标题:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
//1.拿到目标控制器
UIViewController *vc = segue.destinationViewController;
//2. 设置目标控制器的标题
vc.navigationItem.title =self.loginText.text;
vc.title = [NSStringstringWithFormat:@"%@的联系人列表",self.loginText.text];
}
另外注意的是,注册一个通知,在这个通知销毁的时候一定要取消监听,
- (void)viewDidLoad {
[superviewDidLoad];
//1.增加两个通知
[[NSNotificationCenterdefaultCenter]addObserver:selfselector:@selector(textChanged)name:UITextFieldTextDidChangeNotificationobject:self.nameText];
[[NSNotificationCenterdefaultCenter]addObserver:selfselector:@selector(textChanged)name:UITextFieldTextDidChangeNotificationobject:self.phoneNumber];
}
/*取消监听*/
- (void)dealloc{
[[NSNotificationCenterdefaultCenter]removeObserver:self];
}
2.从后一个界面传值到前一个界面 这里比上面稍微复杂些,方法也比较多
假设我们现在要从LWAddViewController传值到LWContactViewController这个界面
2.1
首先,我们在LWContactViewController声明一个设置值的方法,代码如下:
- (void)setName:(NSString *)name andNumber:(NSString *)num;
在.m文件中是对该方法的实现我们先简单的打印一下,看看值能不能正确的传递过来
- (void)setName:(NSString *)name andNumber:(NSString *)num{
NSLog(@"name = %@ num = %@",name,num);
}
在LWAddViewController中 先来声明一个LWContactViewController对象的属性
/*声明一个contactVC属性*/
@property (nonatomic,strong) LWContactViewController *Contact;
导入前一个页面的头文件在点击跳转的按钮方法中 实现以下代码:
/*点击添加按钮*/
- (IBAction)addBtnClickd {
LWContactViewController *conc = [[LWContactViewController alloc]init];
self.Contact = conc;
[self.Contact setName:self.nameText.text andNumber:self.phoneNumber.text];
[self.navigationController popViewControllerAnimated:YES];
}
2.2 我们知道,无论是自动类型还是手动类型的segue 都会在跳转前执行这个方法
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
/*取出目标控制器*/
LWAddViewController *addVC = (LWAddViewController *)segue.destinationViewController;
/*设置目标控制器的来源控制器属性*/
addVC.contact = self;
}
- (IBAction)addBtnClickd {
[self.contact setName:self.nameText.text andNum:self.phoneNumber.text];
}
/*实现一个协议*/
@protocol LWAddViewControllerDelegate <NSObject>
- (void)addViewControllerAddBtnClicked:(LWAddViewController *)addViewController;
@end
/*实现一个代理*/
@property (nonatomic,weak) id<LWAddViewControllerDelegate> delegate;
/*点击添加按钮*/
- (IBAction)addBtnClickd {
/*如果能响应这个事件*/
if ([self.delegate respondsToSelector:@selector(addViewControllerAddBtnClicked:)]) {
[self.delegate addViewControllerAddBtnClicked:self];
}
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
LWAddViewController *addVC = (LWAddViewController *)segue.destinationViewController;
addVC.delegate = self;
}
再实现代理方法:/*实现代理方法*/
- (void)addViewControllerAddBtnClicked:(LWAddViewController *)addViewController{
NSLog(@"成功添加了新联系人!");
}
点击运行 就能成功打印出来了 但是这样写仍然有需要完善的地方 因为两个viewcontroller都需要互相import对方 耦合度太高了 显然这不是我们希望看到的 解决方法是,将需要传递的数据对象抽象成一个模型 实现代码:#import <Foundation/Foundation.h>
LWContact中定义了两个属性 name和num
@interface LWContact : NSObject
@property (nonatomic,copy) NSString *name;
@property (nonatomic,copy) NSString *num;
@end
@protocol LWAddViewControllerDelegate <NSObject>
/*协议*/
- (void)addViewControllerAddBtnClicked:(LWContact *)contact;
@end
在执行跳转传数据的按钮的响应方法中 实现以下代码:
- (IBAction)addBtnClickd {
/*是否能响应*/
if ([self.delegate respondsToSelector:@selector(addViewControllerAddBtnClicked:)]) {
LWContact *contact = [[LWContact alloc]init];
contact.name = self.nameText.text;
contact.num = self.phoneNumber.text;
[self.delegate addViewControllerAddBtnClicked:contact];
[self.navigationController popViewControllerAnimated:YES];
}
}
注意到了没 假使以后产品经理对产品需求发生了变化,需要我们往属性中添加新属性 我们不必再修改很多地方 一个一个添加新增的属性参数 只需要在模型中进行修改即可/*实现代理方法*/
- (void)addViewControllerAddBtnClicked:(LWContact *)contact{
NSLog(@"name = %@ num = %@",contact.name,contact.num);
}