IOS 学习笔记 页面跳转和页面导航

目录

1 导航模式的种类

1.1 平铺式导航

1.2 标签式导航

1.3 树形结构式导航

2 视图控制器的种类

2.1 使用UIViewController实现页面跳转

2.1.1 首先在故事板的View Controller的顶部添加一个NavigationBar

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 测试效果图


 

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

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

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

 

1 导航模式的种类

1.1 平铺式导航

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

IOS 学习笔记 页面跳转和页面导航

 

1.2 标签式导航

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

IOS 学习笔记 页面跳转和页面导航

 

1.3 树形结构式导航

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

IOS 学习笔记 页面跳转和页面导航

 

2 视图控制器的种类

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

 

 

 

 

 

 

 

 

 

 

 

 

2.1 使用UIViewController实现页面跳转

2.1.1 布局第一个页面

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

IOS 学习笔记 页面跳转和页面导航

2.1.2 调出Navigation Controller

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

IOS 学习笔记 页面跳转和页面导航

IOS 学习笔记 页面跳转和页面导航

IOS 学习笔记 页面跳转和页面导航

2.1.3 给导航栏添加一个标题

 

IOS 学习笔记 页面跳转和页面导航

2.1.4 给NavigationBar添加跳转按钮

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

IOS 学习笔记 页面跳转和页面导航

 

2.1.5 添加第二个页面

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

IOS 学习笔记 页面跳转和页面导航

 

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

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

IOS 学习笔记 页面跳转和页面导航

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

IOS 学习笔记 页面跳转和页面导航

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

IOS 学习笔记 页面跳转和页面导航

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

IOS 学习笔记 页面跳转和页面导航

 

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

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

IOS 学习笔记 页面跳转和页面导航

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

IOS 学习笔记 页面跳转和页面导航

 

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 测试效果图

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

IOS 学习笔记 页面跳转和页面导航

 

 

3 纯代码实现页面间跳转

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

3.1 xib布局页面,实现页面见跳转

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

这里遇到个问题,只是在xib中布局后往对应的ViewController拖拽生成一个

@property (weak, nonatomic) IBOutlet UIBarButtonItem *nextButton;居然会报错,错误如下,目前卡住了,网上的方法都不好使:

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
	2   CoreFoundation                      0x000000010cd17d29 -[NSException raise] + 9
	3   Foundation                          0x000000010bce1de4 -[NSObject(NSKeyValueCoding) setValue:forKey:] + 292
	4   UIKitCore                           0x000000010f558292 -[UIViewController setValue:forKey:] + 87
	5   UIKitCore                           0x000000010f7ef573 -[UIRuntimeOutletConnection connect] + 109
	6   CoreFoundation                      0x000000010cd03cfd -[NSArray makeObjectsPerformSelector:] + 317
	7   UIKitCore                           0x000000010f7ec2b9 -[UINib instantiateWithOwner:options:] + 1814
	8   UIKitCore                           0x000000010f55f452 -[UIViewController _loadViewFromNibNamed:bundle:] + 383
	9   UIKitCore                           0x000000010f55fddc -[UIViewController loadView] + 177
	10  UIKitCore                           0x000000010f5600ee -[UIViewController loadViewIfRequired] + 175
	11  UIKitCore                           0x000000010f560940 -[UIViewController view] + 27
	12  UIKitCore                           0x000000010fbb7c53 -[UIWindow addRootViewControllerViewIfPossible] + 122
	13  UIKitCore                           0x000000010fbb836e -[UIWindow _setHidden:forced:] + 294
	14  UIKitCore                           0x000000010fbcb5c0 -[UIWindow makeKeyAndVisible] + 42
	15  ControllerSimple                    0x000000010b998601 -[AppDelegate application:didFinishLaunchingWithOptions:] + 545
	16  UIKitCore                           0x000000010fb76bde -[UIApplication _handleDelegateCallbacksWithOptions:isSuspended:restoreState:] + 280
	17  UIKitCore                           0x000000010fb785cb -[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 3979
	18  UIKitCore                           0x000000010fb7dc2f -[UIApplication _runWithMainScene:transitionContext:completion:] + 1623
	19  UIKitCore                           0x000000010f39c4e9 __111-[__UICanvasLifecycleMonitor_Compatability _scheduleFirstCommitForScene:transition:firstActivation:completion:]_block_invoke + 866
	20  UIKitCore                           0x000000010f3a529c +[_UICanvas _enqueuePostSettingUpdateTransactionBlock:] + 153
	21  UIKitCore                           0x000000010f39c126 -[__UICanvasLifecycleMonitor_Compatability _scheduleFirstCommitForScene:transition:firstActivation:completion:] + 233
	22  UIKitCore                           0x000000010f39cae0 -[__UICanvasLifecycleMonitor_Compatability activateEventsOnly:withContext:completion:] + 1085
	23  UIKitCore                           0x000000010f39acb5 __82-[_UIApplicationCanvas _transitionLifecycleStateWithTransitionContext:completion:]_block_invoke + 795
	24  UIKitCore                           0x000000010f39a95f -[_UIApplicationCanvas _transitionLifecycleStateWithTransitionContext:completion:] + 435
	25  UIKitCore                           0x000000010f39fa90 __125-[_UICanvasLifecycleSettingsDiffAction performActionsForCanvas:withUpdatedScene:settingsDiff:fromSettings:transitionContext:]_block_invoke + 584
	26  UIKitCore                           0x000000010f3a080e _performActionsWithDelayForTransitionContext + 100
	27  UIKitCore                           0x000000010f39f7ef -[_UICanvasLifecycleSettingsDiffAction performActionsForCanvas:withUpdatedScene:settingsDiff:fromSettings:transitionContext:] + 221
	28  UIKitCore                           0x000000010f3a493a -[_UICanvas scene:didUpdateWithDiff:transitionContext:completion:] + 392
	29  UIKitCore                           0x000000010fb7c44e -[UIApplication workspace:didCreateScene:withTransitionContext:completion:] + 515
	30  UIKitCore                           0x000000010f720d09 -[UIApplicationSceneClientAgent scene:didInitializeWithEvent:completion:] + 357
	31  FrontBoardServices                  0x00000001182d12da -[FBSSceneImpl _didCreateWithTransitionContext:completion:] + 448
	32  FrontBoardServices                  0x00000001182dc443 __56-[FBSWorkspace client:handleCreateScene:withCompletion:]_block_invoke_2 + 271
	33  FrontBoardServices                  0x00000001182dbb3a __40-[FBSWorkspace _performDelegateCallOut:]_block_invoke + 53
	34  libdispatch.dylib                   0x000000010e616602 _dispatch_client_callout + 8
	35  libdispatch.dylib                   0x000000010e619b78 _dispatch_block_invoke_direct + 301
	36  FrontBoardServices                  0x0000000118310ba8 __FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 30
	37  FrontBoardServices                  0x0000000118310860 -[FBSSerialQueue _performNext] + 457
	38  FrontBoardServices                  0x0000000118310e40 -[FBSSerialQueue _performNextFromRunLoopSource] + 45
	39  CoreFoundation                      0x000000010cc7d721 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
	40  CoreFoundation                      0x000000010cc7cf93 __CFRunLoopDoSources0 + 243
	41  CoreFoundation                      0x000000010cc7763f __CFRunLoopRun + 1263
	42  CoreFoundation                      0x000000010cc76e11 CFRunLoopRunSpecific + 625
	43  GraphicsServices                    0x00000001153101dd GSEventRunModal + 62
	44  UIKitCore                           0x000000010fb7f81d UIApplicationMain + 140
	45  ControllerSimple                    0x000000010b9983b0 main + 112
	46  libdyld.dylib                       0x000000010e68c575 start + 1
	47  ???                                 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb) 

最关键的一句话是:this class is not key value coding-compliant for the key nextButton,我就纳闷了,不可能有重复的引用,就是无法通过,目前正在处理中... ...