iOS页面跳转

UINavigationController:
里面有个viewControllers属性,是个栈(NSArray,lastObject为顶)存储VC。栈顶就是当前展示的页面。
 
uiNavigationController类似flutter的Navigator,保存了页面栈,方法为pushviewController和popviewConroller。
普通的uiviewcontroller对应的有presentViewController和dismissViewController方法。
 
二者区别:
1.pushViewController 导航控制器入栈的方式切换页面
presentViewController 模态切换的方式切换页面【模态:https://www.jianshu.com/p/a6297a04bf01
2.present只能逐级返回,push所有视图由视图栈控制,可以返回上一级,也可以返回到根vc,其他vc。
3.模态视图从屏幕下方滑出来,完成的时候需要关闭这个模态视图,如果不关闭,就不能做别的事情,必须有响应处理的含义。(相当类似于flutter的showbottomsheet弹窗!)
 
我理解的使用场景:
push/pop更多适用于不同业务页面的跳转(返回某制定页面/首页)
present/dismiss适用于弹窗,弹一下必须关掉(名字也看得出:呈现/开除,就是昙花一现)
 
注意点:present一个uiviewcontroller过去新页面后,self.navigationcontroller是nil。想在当前页面也能返回之前
 

 

写了三个VC,初始的tabVC是VC1,灰色背景是VC2,黄色背景是VC3。

 

VC1进入VC2是present,VC2进入VC3是push。

 

 注意点:从一个页面A present一个新页面B,B页面的self.navigationController是nil,即使你在B里新建navController,rootVC指向self(B),也无法从B页面push到任何新页面。

正确方式是:从页面A新建一个navController,rootVC指定为B;然后present:navController;这样可以正常present B页面,并且打断点可以发现此时B页面中的navigationController属性就是传进来的那个navController;从B页面可以直接push任何新页面;当然从B返回A页面还是要用dismiss,毕竟A到B是present方式,来去的方式要一致才行(push--pop,present--dismiss)。

 

代码:

//
//  AppDelegate.m
//  wzy_ios_demo
//
//  Created by Wzy on 2020/12/21.
//

#import "AppDelegate.h"
#import "ViewController.h"

@interface AppDelegate ()


@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    
    //1.创建Window
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.window.backgroundColor = [UIColor whiteColor];

    //a.初始化一个tabBar控制器
    UITabBarController *tb=[[UITabBarController alloc]init];
    //设置控制器为Window的根控制器
    self.window.rootViewController=tb;

    //b.创建子控制器
    ViewController *c1=[[ViewController alloc]init];

    UINavigationController *nc1 = [[UINavigationController alloc] initWithRootViewController:c1];
    nc1.view.backgroundColor=[UIColor grayColor];
    nc1.view.backgroundColor=[UIColor greenColor];
    nc1.tabBarItem.title=@"消息";
    nc1.tabBarItem.image=[UIImage imageNamed:@"tab_recent_nor"];
    nc1.tabBarItem.badgeValue=@"123";

    ViewController *c2=[[ViewController alloc]init];

    UINavigationController *nc2 = [[UINavigationController alloc] initWithRootViewController:c2];
    nc2.view.backgroundColor=[UIColor brownColor];
    nc2.tabBarItem.title=@"联系人";
    nc2.tabBarItem.image=[UIImage imageNamed:@"tab_buddy_nor"];

    ViewController *c3=[[ViewController alloc]init];

    UINavigationController *nc3 = [[UINavigationController alloc] initWithRootViewController:c3];
    nc3.tabBarItem.title=@"动态";
    nc3.tabBarItem.image=[UIImage imageNamed:@"tab_qworld_nor"];

    ViewController *c4=[[ViewController alloc]init];

    UINavigationController *nc4 = [[UINavigationController alloc] initWithRootViewController:c4];
    nc4.tabBarItem.title=@"设置";
    nc4.tabBarItem.image=[UIImage imageNamed:@"tab_me_nor"];
       

    //c.添加子控制器到ITabBarController中
    //c.1第一种方式
    //[tb addChildViewController:nc1];
    //[tb addChildViewController:nc2];

    //c.2第二种方式
    tb.viewControllers=@[nc1,nc2,nc3,nc4];


    //2.设置Window为主窗口并显示出来
    [self.window makeKeyAndVisible];


    return YES;
}

@end

 

//
//  ViewController.m
//  wzy_ios_demo
//
//  Created by Wzy on 2020/12/21.
//

#import "ViewController.h"
#import "MyView.h"
#import "ViewController2.h"


@interface ViewController ()


@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(100, 100, 50,20)];
    button.backgroundColor = [UIColor grayColor];
    [button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    [button addTarget:self action:@selector(func) forControlEvents:UIControlEventTouchUpInside];
    [button setTitle:@"blah" forState:UIControlStateNormal];
    self.navigationItem.hidesBackButton=NO;
    [self.view addSubview: button];
}

- (void)func{
    ViewController2 *vc2 = [[ViewController2 alloc] init];
    
//    [self.navigationController pushViewController:vc2 animated:YES];    //pushViewController调用
    
    //使用模态路由必须新建navigationcontroller,不然过去新的页面,新页面self.navigationcontroller是nil!
    
    UINavigationController *navCtrller = [[UINavigationController alloc] initWithRootViewController:vc2];
    
    [vc2 setModalPresentationStyle: 0];
    [self presentViewController:navCtrller animated:YES completion: ^(void) {
        NSLog(@"callback");
    }];
   
}

- (void)callback {
    NSLog(@"callback");
}

- (void)pop {
    [self.navigationController popViewControllerAnimated:YES];
}

@end

 

//
//  ViewController2.m
//  wzy_ios_demo
//
//  Created by Wzy on 2020/12/22.
//

#import "ViewController2.h"
#import "ViewController3.h"

@interface ViewController2 ()

@end

@implementation ViewController2

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor grayColor];
    
    UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(150, 150, 100,40)];
    button.backgroundColor = [UIColor whiteColor];
    [button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    [button addTarget:self action:@selector(onTap) forControlEvents:UIControlEventTouchUpInside];
    [button setTitle:@"点我返回" forState:UIControlStateNormal];
    
    UIButton *button2 = [[UIButton alloc] initWithFrame:CGRectMake(150, 250, 100,40)];
    button2.backgroundColor = [UIColor whiteColor];
    [button2 setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    [button2 addTarget:self action:@selector(onTap2) forControlEvents:UIControlEventTouchUpInside];
    [button2 setTitle:@"点我进入" forState:UIControlStateNormal];
    
    self.navigationItem.hidesBackButton=NO;
    [self.view addSubview: button];
    [self.view addSubview: button2];
    
//    UIBarButtonItem * buttonItem = [[UIBarButtonItem alloc]initWithTitle:@"回去" style:UIBarButtonItemStyleDone target:self action:@selector(tapLeftButton:)];
//        [buttonItem setImage:[UIImage imageNamed:@"back"]];
//    self.navigationItem.leftBarButtonItem= buttonItem;
//    self.navigationItem.title = @"我最帅";
}

- (void)tapLeftButton:(UIButton *)sender
{
    [self.navigationController popViewControllerAnimated:YES];
}

- (void)onTap {
    [self dismissViewControllerAnimated:YES completion:nil];
}

- (void)onTap2 {
    [self.navigationController pushViewController:[[ViewController3 alloc] init] animated:YES];
}

@end

 

//
//  ViewController3.m
//  wzy_ios_demo
//
//  Created by Wzy on 2020/12/23.
//

#import "ViewController3.h"

@interface ViewController3 ()

@end

@implementation ViewController3

- (void)viewDidLoad {
    [super viewDidLoad];
    [self.view setBackgroundColor: [UIColor yellowColor]];
    // Do any additional setup after loading the view.
}

/*
#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

 

posted @ 2020-12-23 10:40  NeoZy  阅读(1016)  评论(0编辑  收藏  举报