大多数应用程序是由主视图导出多个屏幕,并且通常情况下实现屏幕切换的方法还不止一种。我们需要一种方式来实现用户在应用程序内来回移动,以及让用户知道他们所在的具体部分提供的功能之间的切换。
在iPhone设备上,大多数使用导航控制器的应用程序可以分为两种。一种使用简单的主视图来导航一系列展示或多或少、渐进的细节场景。通讯录、笔记和设置就是不错的示例。其他的,比如闹钟和音乐,则有许多主视图,各自拥有不同的功能,设置拥有自己的内容层次。
iOS提供控制器来管理每种内容之间的导航。UINavigationController用于在各种层次结构的信息之间上下移动,而UITabBarController则处理多个主视图之间的切换。
本节就是介绍这两种方法怎么使用。
我们来看一下设置是长啥样的吧,下图展示的是setting方法应用程序中的某个局部的层级结构
在iPhone上,这是常见的组织内容的方式。该方式优雅地解决了如何在狭小空间内显示大量内容的问题。setting允许修改iPhone和setting内部各种应用程序的数以百计的设置选项。采用层次结构的方式来“折叠”内容,能够很好地应用两种屏幕尺寸,以及很好地复合人们通常善于分类和分组的情况。
那些拥有带层次结构的内容的应用程序,工作方式一般基本相同。在屏幕层级的顶部,会有内容概述,然后就是多个带更多细节的屏幕。setting应用程序就是不错的示例。在顶层,一开始是setting应用的所有相关的分类,然后是能够持续向下深入,直到到达特定设置的细节。
UINavigationController正是为了处理这种类型的导航而设。他跟踪客户,就像它位于导航中不同屏幕的层次结构,并提供默认的控件返回。该控制器通过将所有内容都嵌入它内部来实现这一点。
上图显示了导航控制器的一部分。顶部是导航栏。导航栏通常会用在上下文中或展开的当前路径。标题通常为用户正在观看的内容。正如我们很快就会看到的一样,在导航路径中,左手边的后退按钮能够让用户返回上一节。在导航栏上,用户可以自定义按钮
位于底部的是一个可选的工具栏,是另一处让我们设置空间的地方,上面放了一个操作按钮。我们的视图控制器位于灰色地带。而在当前场景的某个地方,需要提供一个方法来打开下一级详细页面。例如,在Add/View场景中的Edit按钮
当使用导航控制器时,一开始可以将它连接到第一个场景或根场景(一个视图控制器)。当导航控制器打开时,他就会打开根场景。正如我们将其关联到一个新的场景(视图控制器),导航控制器会将它放在当前路径上,并显示该场景。
在视图控制器的堆栈中,根视图位于底部,路径通常也会被记录。
所有的导航功能都通过5个主要类来提供:
UIToolbar管理一个可选的工具栏,通常位于屏幕的底部。其拥有方法与属性来设置Button Item(按钮项)和外观,以及一种方式来指定其位置是在屏幕的顶部还是底部
UINavigationItem使用当前视图控制器的title属性来设置文本。更改title会改变文本。之前在本地化的场景标题我们见过这个操作。
下图显示了在CarValet应用程序的Add/View场景中与导航控制器相关的对象
导航控制器管理Add/View场景以及其他场景。每个被管理的场景有一个UINavigationItem,用于设置导航栏的内容以及标题。Add/View场景的标题栏也有一个工具栏按钮,以显示car images场景。
观看上图的圈圈,这是一个特殊的关联标识符(segue identifier),是为第一个控制器或根视图控制器而设。不想push segue,着开起来想一条两端都有一个圆的线。根场景是导航控制器展示的第一个场景。故事版中的另一个链接显示了场景之间的导航路径。例如在Add/View于Edit场景之间存在一个链接。因为无处可去只有返回,Edit场景就是一个叶节点,如同第一张图的叶节点。
(从书上抄了那么多字真是类,觉得还是介绍一下比较好),现在开始干正事。
首先我们要把图标添加到项目的资产库中。我们需要图标,可以
在这里下载,但是那需要自己找;也可以在这里我的github下载。最好是从我的github上下载吧。
好了,图标下载完了,要添加到资产库中,如下图操作方式
选+之后,会跳出一个目录,到最下面找到Import,点完import,选中要导入的文件就行啦
选择左边的按钮,Image设置为sign_out;右边那个按钮,Image设置为sign_in;中间的按钮,title改为Edit。
删除原来的Previous、Next和Edit按钮,
将我们之前添加的左右箭头通过下图方法设置关联,左箭头选择previousCar,右箭头选择nextCar
当我们删除Edit按钮时,也删除了到Edit场景的关联(segue),我们要将它恢复,将它拉到Edit场景,选择push,并设置标识符为Editsegue,与之前的Edit按钮所用的关联名称一样
然后运行程序你可能会发现下面的导航栏没有出现,那么在ViewController.m中的viewDidLoad方法中,添加self.navigationController.toolbarHidden = NO;
使他正好位于[super viewDidLoad];
下面,这时候就出现了,但是点开其他的例如car images,下面也出现了导航栏,这显然不是我们想要的,在Edit等场景里面也是这个情况。可以在他们各自的viewDidLoad方法中添加self.navigationController.toolbarHidden = YES;
,这样就默认为隐藏了。然而还有个问题,当我们从其他场景退出返回到Add/View场景时,导航栏消失了,他也是被隐藏了,那我们就换个地方,在ViewController.m中的viewWillAppear方法中,添加self.navigationController.toolbarHidden = NO;
,这样每次加载的时候,就自动设置回去了。这样就设置完成啦。
(PS,颜色是我后来弄的,到这步按钮颜色应该是蓝色的,导航栏应该是白色的,而且没有About)
到目前为止,我们已经使用segue在场景之间进行导航,包括使用特使的exit segue。我们拥有一些控制器可以传递数据并能使用prepareForSegue:方法修改行为。借助于UINavigationController的属性和消息,可以拥有完全控制权。可以实现如下类似行为:将新的视图控制器推给堆栈(push),弹出(pop)当前视图控制器,弹出根视图控制器之上的所有控制器,获取当前导航堆栈中的控制器数组,甚至重新排列视图控制器数组。
可以使用基于代码的消息,为CarValet应用程序添加一个About场景,而不是在故事面板中添加,而是可以在单独的用户界面资源文件中创建界面。在Xcode中,这些文件是XIB文件
实现步骤如下:
- (IBAction)aboutCarValet:(id)sender {AboutViewController *nextController;nextController = [[AboutViewController alloc]initWithNibName:@"AboutViewController"//1bundle:[NSBundle mainBundle]];nextController.title = @"About CarValet";//2[self.navigationController pushViewController:nextController animated:YES];
}
注释:
运行结果:
我们在IB中,有时候会看到Tint(色调)选项。使用此选项是为用户体验增加彩色主题的快速方法。需要注意的是,它与VIew区域中改变背景色是不同的。
对UINavigationController来说,可以更改导航栏、工具栏和工具栏按钮的色调。为事物设置色调的工作由导航控制器进行管理,导航控制器会改变它管理的每个屏幕上该事物的颜色。
打开故事面板,自行修改颜色。
可能会遇到工具栏色调不起作用,那么我们可以用代码实现,在ViewController.m中的viewDidLoad方法下,添加
UIColor *sky = [UIColor colorWithDisplayP3Red:102.0/255.0 green:204.0/255.0 blue:255.0/255.0 alpha:1.0];self.navigationController.toolbar.barTintColor = sky;
这时候颜色就添加完啦,本程序还添加了其他颜色,配色方案如下
用户界面元素 | 苹果蜡笔颜色 | RGB |
---|---|---|
工具栏 | SKY | R:102 G:204 B:255 |
标题 | snow(white) | R:255 G:255 B:255 |
按钮 | Mocha | R:128 G:64 B:0 |
但是我们上面的方法只能更改一个屏幕里面的颜色,以下代码是更改全部,在AppDelegate.m文件中
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {// Override point for customization after application launch.UIColor *Mocha = [UIColor colorWithDisplayP3Red:128.0/255 green:64.0/255.0 blue:0/255.0 alpha:1.0];[[UIButton appearance]setTitleColor:Mocha forState:UIControlStateNormal];[[UIBarButtonItem appearance] setTintColor:Mocha];return YES;
}
其中,最后两行是通过appearance protocol协议修改按钮,工具栏按钮颜色。
好了,导航控制器的使用就暂时介绍到这里咯。
本想找clock程序作为用例的,模拟器上竟然没有。换成健康
看到下面的健康数据,今天,数据来源这些选项了吧,这些是标签栏,每个栏对应不同的功能,而且有的栏里面还有多个屏幕。
使用UITabBarController时,每个功能区域或标签栏都是根视图,实际上,标签栏控制器是应用程序真正的根视图,简单的画一下。
标签栏控制器使用如下三个主要类:
图片什么的之前已经导入了
(PS,运行到这里,标签栏中应该是只有一个图标,圆形的还是方形的晚了)
这时候是只有一个选项卡的,我就不运行了。现在我们将car image场景添加为第二个选项卡
从标签栏拉到Car Images场景,从Relationship Segue类别中选择视图控制器。这是就添加上去了。
更换图标
然而运行的时候发现reset没用
进行以下步骤修改:
ok,运行程序就行啦。
我们通过代码的形式添加about到标签栏
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {// Override point for customization after application launch.UIColor *Mocha = [UIColor colorWithDisplayP3Red:128.0/255 green:64.0/255.0 blue:0/255.0 alpha:1.0];[[UIButton appearance]setTitleColor:Mocha forState:UIControlStateNormal];[[UIBarButtonItem appearance] setTintColor:Mocha];UITabBarController *tabBarController = (UITabBarController*)self.window.rootViewController;//1//2AboutViewController *aboutViewController = [[AboutViewController alloc]initWithNibName:@"AboutViewController"bundle:[NSBundle mainBundle]];UITabBarItem *aboutItem = [[UITabBarItem alloc]initWithTitle:@"About" //3image:[UIImage imageNamed:@"tag"]tag:0];[aboutViewController setTabBarItem:aboutItem];//4NSMutableArray *currentItems = [NSMutableArray arrayWithArray:tabBarController.viewControllers];//5[currentItems addObject:aboutViewController];//6[tabBarController setViewControllers:currentItems animated:NO];//7return YES;
}
注释:
在应用程序启动时,以不带动画效果的方式更新选项卡数组。如果该操作是在应用程序因用户行为而运行时发生,那么我们可能愿意以动画效果更新变化
好了运行程序,再次贴图:
今天的介绍就到这里咯
我的另一个博客站点:Arnold-你们好啊