2021-09-18


目录

1 导航模式的种类

1.1 平铺式导航

1.2 标签式导航

1.3 树形结构式导航

2 视图控制器的种类

2.1 使用UIViewController实现页面跳转

2.1.1 故事板布局

2.1.2 调出Navigation Controller

2.1.3 给导航栏添加一个标题

2.1.4 给NavigationBar添加跳转按钮

2.1.5 添加第二个页面

2.1.6 将“下一页”按钮和和第二页关联起来,点击后能够跳转

2.1.7 Main.storyboard上的页面和具体类绑定

2.1.8 具体代码

2.1.9 测试效果图

3.1 xib布局实现页面见跳转

3.1.1 xib布局页面

3.1.2 xib 中IBOutlet生成引用变量后运行报错原因检查

3.1.3  添加第二个页面

3.1.4 xib布局页面跳转运行效果

上一章笔记中记录了NavigationBar的简单使用,并没有真正的使用它做页面之间的跳转,这里说说的页面跳转不是类似Android的Fragment之间的跳转,而是类似于Android中的从Activity跳转到另一个Activity,这一章将记录学习页面件跳转的内容。

Cocoa Touch遵循了MVC的模式,这里学习的页面间的跳转也就是官方所说的导航,从一个View Controller到另一个View Controller。

视图控制器又很多种类,其中不仅能够显示视图,也就是用户界面,也起到导航的作用。

1 导航模式的种类

1.1 平铺式导航

平铺式导航有分屏和分页,在内容上是没有层级关系的,展示的内容都放在一个屏幕中,可以左右或者上下滑动,如:

 

1.2 标签式导航

将应用按照功能划分为多个功能模块,彼此之间独立,通过tab来切换各个功能模块,如下图:

 

1.3 树形结构式导航

属性结构的导航模式类似树形结构,分为枝叶,那些树叶属于那个枝干,是有层级俄关系的,典型的树形结构导航就是邮箱,如下图:

 

2 视图控制器的种类

视图控制器    视图控制器的在导航上的作用
UIViewController    可用于自定义视图控制器的导航,用于界面间的跳转,比如用一个UIViewController控制另外2个UIViewController工作。
UINavigationController    导航控制器,可以与UITableViewController结合使用,
UITabBarController    标签栏控制器,可用于构建标签式导航模式
UIPageViewController    电子书风格的导航控制器,主要用电子书和电子杂志类的应用开发,是IOS最近才推出的。
UISplitViewController    主要用于ipad应用开发,分割屏幕风格的视图控制器
UIPopoverController    主要用于ipad应用开发,气泡风格的控制器
      
 

2.1 使用UIViewController实现页面跳转

2.1.1 故事板布局

首先在故事板的View Controller的顶部添加一个NavigationBar,中间添加一个Label,如下图:

 

2.1.2 调出Navigation Controller

故事板中选中 View Controller > 标题栏 Editor > Embed In > Navigation Contoller,调出Navigation Controller,如下图

 

 

 

2.1.3 给导航栏添加一个标题

 

2.1.4 给NavigationBar添加跳转按钮

然后给NavigationBar 右边加一个跳转按钮 文案“下一页”

 

2.1.5 添加第二个页面

从视图对象库中拖拽一个View Controller放入故事板中,并重复第二步骤中的方法,调出Navigation Controller

 

2.1.6 将“下一页”按钮和和第二页关联起来,点击后能够跳转

按住contrl键,点击“下一页”按钮拖拽到第二个 Navigation Controller,也就是第二个控制器,弹出对话框选中show,然后可以看到中间生成了一个带圆圈的箭头,

 

上面gif图演示了将两个场景关联的过程,然后生成下面图的关系,注意蓝色的框是Navigation Controller和自己View Controller的联系,这个是内在的,红色的框表示两个场景的关联,这样4个Controller就关联起来了。

 

然后给第二个界面的NavigationBar左侧添加一个返回按钮,并将这个按钮用同样的方法和第一个Navigation Contoller关联起来买就会出翔下面的折线箭头,意思是点击返回,回到第一个界面

 

注意下面红色方框中的箭头,表示是进入的第一个界面,如果我们在运行后发现界面是黑屏,肯定是这一个没有设置,这篇笔记的这个列子这箭头一定是从下面开始的,如果没有设置,记得选中进入的Controller,把右边的IS Initial View Controller勾选上,这里类似与Android中的清单文件中设置某一个Activity为启动页面一样。

 

2.1.7 Main.storyboard上的页面和具体类绑定

Main.storyboard上的每一个界面都需要有一个UIViewController与之对应,所以我们需要创建一个SecondViewController类,并让它和第二个页面关联起来。

 

紧接着将联故事板中的Pager和类关联起来,接下来关联的是SecondViewController

 

2.1.8 具体代码

第一个页面的类都是xcode生成的没有任何改动

#import "ViewController.h"
 
@interface ViewController ()
 
@end
 
@implementation ViewController
 
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}
 
 
@end
 
第二个页面的类基本也是xcode生成的,只是手动增加了一个UILabel,其实也可以直接在Interface Builder里面拖拽生成,这里只是为了验证是否有作用,是否可以在里面编辑第二个界面。

#import "SecondViewController.h"
 
@interface SecondViewController ()
 
@end
 
@implementation SecondViewController
 
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 124, 120, 30)];
    label.text = @"第二个页面";
    [self.view addSubview:label];
    
}
 
 
@end
 

2.1.9 测试效果图

点击“下一页”,进入第二个页面,点击“返回”回到第一个页面

 

3.1 xib布局实现页面见跳转

上面通过拖拽的方式很简单直观的学习了使用Navigation Controller 控制多个View Controller相互跳转,首先能够有可以下手的兴趣,那么问题来了,不是所有的时候都通过这种方式来做跳转,有时候也会只使用代码来做。使用纯代码实现起来,就稍许有点麻烦了。

3.1.1 xib布局页面

这里有个新需求需要完成,将上面故事板对应的界面使用xib分解成两个独立的存在,也就是一个xib对应一个界面,共2个界面,使用两个xib文件和ViewController,并让xib和自己对应的ViewController类相关联,然后做到上面相同的效果,不知道怎么使用xib布局的同学可以移步《IOS 学习笔记 使用xib文件构建界面》先看看看怎么操作。

这里遇到个问题,在xib中布局后,往对应的ViewController拖拽生成一个属性变量,如下

生成:@property (weak, nonatomic) IBOutlet UIBarButtonItem *nextButton;

源码:

#import "RootViewController.h"
 
@interface RootViewController ()
@property (weak, nonatomic) IBOutlet UIBarButtonItem *nextButton;
 
@end
 
@implementation RootViewController
 
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
}
 
 
@end
居然会报错,错误如下,如何解决,目前卡住了,网上的方法都不好使:

2019-04-19 22:15:21.875193+0800 ControllerSimple[44628:1688645] libMobileGestalt MobileGestalt.c:890: MGIsDeviceOneOfType is not supported on this platform.
2019-04-19 22:15:21.951738+0800 ControllerSimple[44628:1688645] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<UIViewController 0x7ffbe1505c30> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key nextButton.'
*** First throw call stack:
(
    0   CoreFoundation                      0x000000010cd181bb __exceptionPreprocess + 331
    1   libobjc.A.dylib                     0x000000010c2b6735 objc_exception_throw + 48
    ... ...
最关键的一句话是:this class is not key value coding-compliant for the key nextButton,这句话的意思是“这个类的编码不兼容nextButton的key-value”,什么意思,让我们查找原因,如果去掉这个nextButton能够运行,但是这个变量却不能用了,而且绑定对应的点击函数也是一样报错。

3.1.2 xib 中IBOutlet生成引用变量后运行报错原因检查

上面步骤之后,引用报错:this class is not key value coding-compliant for the key nextButton

1)File's Owner的class属性是否正确

经过检查完全没有问题,如下图:

 

2)IBOutlet的引用是否有多个

经过检查也并没有出现多个

 

3) AppDelegate中添加的ViewController的问题

仔细思考之后,既然上面的问题都不存在,而且根据“this class is not key value coding-compliant for the key ”的意思,似乎是根本就是类加载的问题,在AppDelegate中我初始化了进入首页RootViewController,那可能是这个原因,之前我们按照《IOS 学习笔记 使用xib文件构建界面》的源码是:

 
 
#import "AppDelegate.h"
 
@interface AppDelegate ()
 
@end
 
@implementation AppDelegate
 
 
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    
    //最后一步将创建xib文件绑定到window界面上
    self.window = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen] bounds]];
    self.window.rootViewController = [[UIViewController alloc]initWithNibName:@"RootViewController" bundle:nil];
    [self.window makeKeyAndVisible];
    return YES;
}
 
 
@end
 

这里就有个问题了,UIViewController其实是系统提供的,对于初学者按照网上的写法直接就写了,其实这里我们并没构建这个类,我们构建的是RootViewController,所以上面写法有问题,而且我也在,《IOS 学习笔记 使用xib文件构建界面》加了一节,解决这个问题,也就是把上面代码中金黄色字体的“UIViewController”换成“RootViewController”,代码如下,更换后RootViewController的颜色就变成了灰色:

 
#import "AppDelegate.h"
#import "RootViewController.h"
 
@interface AppDelegate ()
 
@end
 
@implementation AppDelegate
 
 
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    CGRect screen = [[UIScreen mainScreen] bounds];
    self.window = [[UIWindow alloc]initWithFrame:screen];
 
    self.window.rootViewController = [[RootViewController alloc] initWithNibName:@"RootViewController" bundle:nil];
    [self.window makeKeyAndVisible];
    return YES;
}
 
 
 
@end
然后运行就没有问题了。

3.1.3  添加第二个页面

步骤根上面一个样,不过可以先添加一个group,鼠标放在主目录,右键选中New Group,输入second,表示第二个页面的group,然后在second组中New File,选中Cocoa Touch Class,输入SecondViewController,并勾选Also create XIB file:

  

 

 

 

 

 

 

   

第二个界面到此初步创建成功,简单布局一下各自的界面,添加一个NavigtionBar ,在NavigationBar上面添加一个返回按钮,点击返回上一个界面:

#import "RootViewController.h"
#import "second/SecondViewController.h"
 
@interface RootViewController ()
@property (strong, nonatomic) IBOutlet UIBarButtonItem *nextButton;
 
@end
 
@implementation RootViewController
 
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
}
 
- (IBAction)onClickNext:(id)sender {
    SecondViewController *secondViewController = [[SecondViewController alloc] init];
    UINavigationController *navigateionController = [[UINavigationController alloc] initWithRootViewController:secondViewController];
    
    [self presentViewController:navigateionController animated:YES completion:^{
        NSLog(@"OK let me enter second!");
    }];
//    [self presentViewController:secondViewController animated:YES completion:^{
//        NSLog(@"OK let me enter second!");
//    }];
}
 

第二个界面需要添加一个返回,代码如下:

#import "SecondViewController.h"
 
@interface SecondViewController ()
@property (strong, nonatomic) IBOutlet UIBarButtonItem *backButton;
 
@end
 
@implementation SecondViewController
 
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
}
 
- (IBAction)onCLickBack:(id)sender {
    [self dismissViewControllerAnimated:YES completion:^{
        NSLog(@"back to MainPage!");
    }];
}
 
 
@end
3.1.4 xib布局页面跳转运行效果

 

4.1 纯代码实现

纯代码实现就不写了,也就是布局都是通过代码来实现的,业务逻辑是一样的。
————————————————
版权声明:本文为CSDN博主「_无问西东」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_36709064/article/details/89395251

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值