iOS控制器间跳转一:UINavigationController
UIWindow显示根导航控制器,跳转到第一个控制器oneViewController
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 
 | UIWindow *window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
 self.window = window;
 
 // 创建导航控制器
 // 创建登陆控制器
 AMLoginViewController *loginVc = [[AMLoginViewController alloc] initWithNibName:NSStringFromClass([AMLoginViewController class]) bundle:[NSBundle mainBundle]];
 
 UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:loginVc];
 
 window.rootViewController = nav;
 
 [window makeKeyAndVisible];
 
 | 
由第一个控制器跳转到第二个控制器TwoViewController
| 12
 3
 
 | 如果导航控制器调用 push,就会把 vc 添加为导航控制器的子控制器TwoViewController *vc = [[TwoViewController alloc] init];
 [self.navigationController pushViewController:vc animated:YES];
 
 | 
由第二个控制器跳转到第三个控制器ThreeViewController
| 12
 
 | ThreeViewController *vc = [[ThreeViewController alloc] init];[self.navigationController pushViewController:vc animated:YES];
 
 | 
由第三个控制器直接跳转到根控制器,或者返回上一个控制器
| 12
 3
 4
 5
 
 | // 返回到根控制器[self.navigationController popToViewController:self.navigationController.childViewControllers[0] animated:YES];
 
 // 返回到上一个控制器
 [self.navigationController popViewControllerAnimated:YES];
 
 | 
只有栈顶控制器的界面才会显示出来,UINavigationController 有个属性是 topViewController 表示栈顶控制器
UINavigationController的子控制器管理
- UINavigationController以栈的形式保存子控制器
| 12
 
 | @property(nonatomic,copy) NSArray *viewControllers;@property(nonatomic,readonly) NSArray *childViewControllers;
 
 | 
| 1
 | - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated;
 | 
| 1
 | - (UIViewController *)popViewControllerAnimated:(BOOL)animated;
 | 
| 1
 | - (NSArray *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated;
 | 
| 1
 | - (NSArray *)popToRootViewControllerAnimated:(BOOL)animated;
 | 
注意:pop方法不是马上将栈顶子控制器拿出栈(销毁),而是在动画完成的时候才会销毁
控制器间跳转二:Modal
除了push之外,还有另一种控制器的切换方式,就是modal。任何控制器都可以通过modal形式展示出来
modal的默认效果:新的控制器从屏幕最底部往上钻,知道覆盖全部控制器位置。
以Modal的形式展示控制器代码如下:
| 12
 
 | self presentViewController:(UIViewController *) animated:(BOOL) completion:^(void)completion
 
 | 
关闭当初Modal出来的控制器
| 12
 3
 
 | [self dismissViewControllerAnimated:(BOOL) completion:^{code
 }]
 
 | 
注意点
- Modal出来的控制器是直接添加到窗口上
- Modal出来控制器后,虽然加到窗口上,但是窗口的跟控制器一直没被销毁
- Modal出来的控制器需要被强引用,不然会被销毁,无法监听控制器事件
- Modal出来的控制器被上一个控制器的presentedViewController属性强引用。
- Modal的常见用法:Modal出导航控制器
Modal的dismiss原理:
- 控制器被dismiss后,会被销毁
- 谁Modal也有权dismiss
- 被modal出来的控制器都可以dissmiss
- 导航控制器上的按钮modal,跳转到带导航控制器的控制器上。dismiss的时候会判断当前控制器有没有导航控制器,有也可以把导航控制器dismiss。
控制器之间的值传递
第一种方法可以用代理,不过比较麻烦,
这里推荐用 block 可以将要传递的值作为参数
在第一个控制器中拿到要跳转的控制器的 block 属性赋值,然后在跳转的控制器中执行 block 代码即可。
例子:将Vc1 控制器接收传值 ,Vc2控制器发送传值消息,为了便于区别和代理传值的 使用 , 将两者放到 一起其中Vc1控制器里 两个UITextField一个接收代理传值的使用,一个接收block 的使用 。
Vc1 :
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 
 | #import "ViewController.h"
 #import "SecondViewController.h"
 @interface ViewController ()<secondViewControllerDelegate>
 - (IBAction)gengxin;
 @property (weak, nonatomic) IBOutlet UITextField *textField;
 @property (weak, nonatomic) IBOutlet UITextField *secTextField;
 @property (nonatomic,strong) SecondViewController *secVc;
 @end
 
 @implementation ViewController
 
 - (void)viewDidLoad {
 [super viewDidLoad];
 
 SecondViewController *secondVc = [[SecondViewController alloc] init];
 [secondVc returnText:^(NSString *showText) {
 NSLog(@"---------%@------------",showText);
 self.secTextField.text = showText;
 }];
 self.secVc = secondVc;
 self.secVc.delegate = self;
 
 }
 - (IBAction)gengxin {
 [self presentViewController:self.secVc animated:YES completion:nil];
 }
 #pragma mark - secondViewControllerDelegate
 - (void)setTextfield:(NSString *)text{
 self.textField.text = text;
 NSLog(@"%@",text);
 }
 @end
 
 | 
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 
 | Vc2 :#import "ViewController.h"
 @protocol secondViewControllerDelegate
 @optional - (void)setTextfield:(NSString *)text;
 @end
 
 typedef void(^returnBlock)(NSString *showText);
 @interface SecondViewController : ViewController
 @property (nonatomic,strong) id delegate;
 
 @property (nonatomic,strong)returnBlock returnTextBlock;
 
 - (void) returnText: (returnBlock)block;
 @end
 
 | 
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 
 | #import "SecondViewController.h"
 
 @interface SecondViewController ()
 @property (nonatomic,weak) UITextField *textField;
 @property (nonatomic,weak) UIButton *saveButton;
 @end
 
 @implementation SecondViewController
 
 - (void)viewDidLoad {
 [super viewDidLoad];
 
 self.view.backgroundColor = [UIColor grayColor];
 UITextField *textField =[[UITextField alloc] init];
 [self.view addSubview:textField];
 [textField setBorderStyle:UITextBorderStyleRoundedRect];
 self.textField = textField;
 self.textField.frame = CGRectMake(100, 100, 100, 100);
 UIButton *save = [[UIButton alloc] init];
 [self.view addSubview:save];
 self.saveButton = save;
 self.saveButton.frame = CGRectMake(200, 200, 100, 70);
 [self.saveButton setTitle:@"确定" forState:UIControlStateNormal];
 self.saveButton.titleLabel.textColor = [UIColor blackColor];
 [self.saveButton addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];
 
 }
 - (void) buttonClick:(id)sender{
 if ([self.delegate respondsToSelector:@selector(setTextField:)]) {
 NSString *text =self.textField.text;
 [self.delegate setTextfield:text];
 }
 [self dismissViewControllerAnimated:YES completion:nil];
 }
 - (void)didReceiveMemoryWarning {
 [super didReceiveMemoryWarning];
 
 
 }
 - (void) returnText:(returnBlock)block
 {
 self.returnTextBlock = block;
 }
 - (void)viewDidDisappear:(BOOL)animated
 {
 
 if (self.returnTextBlock !=nil) {
 self.returnTextBlock(self.textField.text);
 }
 NSLog(@"======%@=======",self.returnTextBlock);
 }
 
 @end
 
 | 
两者之间的理解方式相同 ,在Vc1传值的里面,将 returenText:方法里的 block值传入 Vc2 控制器里,在控制器 Vc2 跳转的时候,可以判断属性里有值,然后再重新加载 Vc1 的时候,就可以将值写入控制器里的 secTextField 里了