首页 > 其他分享 >iOS开发系列课程(05) --- 导航视图控制器

iOS开发系列课程(05) --- 导航视图控制器

时间:2023-06-20 14:34:43浏览次数:46  
标签:控制器 nil 05 iOS 视图 UIBarButtonItem 导航 属性


简介

  导航视图控制器是一个特殊的容器视图控制器,它可以维护有明确层次关系的视图之间的切换。我们可以打开模拟器或者你的iPhone看看设置功能,这里就是一个典型的对导航视图控制器的应用,如下图所示。很明显,导航视图控制器维护了一个栈结构,这是一种先进后出(FILO)的结构,我们将一个一个的视图压入栈中,当我们想返回的时候就可以依次出栈。

iOS开发系列课程(05) --- 导航视图控制器_导航条

创建导航控制器

  • -initWithRootViewController::在创建导航控制器时指定根视图控制器
  • -initWithNavigationBarClass:toobarClass::用指定的导航条创建导航视图控制器

控制器的入栈和出栈

  • -pushViewController:animated:方法:将一个视图控制器压入栈中
  • -popViewControllerAnimated:方法:从栈中弹出一个视图控制器
  • -popToRootViewControllerAnimated:方法:从栈中直接弹出根视图控制器
  • -popToViewController:animated:方法:从栈中弹出指定的视图控制器

iOS开发系列课程(05) --- 导航视图控制器_导航条_02

  可以通过UINavigationController的viewControllers属性获得其栈中保存的所有视图控制器;topViewController可以获得栈顶的视图控制器。

UINavigationBar

  一个导航视图控制器通常是由以下几个部分构成的:

iOS开发系列课程(05) --- 导航视图控制器_工具条_03

导航条半透明以及相关坐标计算

  导航视图控制器会维持一个导航条(UINavigationBar),这个导航条被所有的视图控制器共享,可以通过UINavigationController对象navigationBar属性获得导航条,再通过下面的属性设置其半透明效果,注意对导航条的设置将对所有的视图控制器生效。

  • translucent属性:设置导航条是否半透明,默认值是YES。对此属性的设置会影响到坐标的计算,因为导航条有44点的高度。例如在视图控制控制器中放置一个按钮,其frame属性的第二个参数设置为100,那么在设置半透明为YES和NO的情况下按钮的呈现效果如下图所示。可以看出设置半透明后的按钮坐标计算是以窗口顶端为参考系的,而不透明的时候按钮坐标是相对于导航条的,相差了44个点。

iOS开发系列课程(05) --- 导航视图控制器_工具条_04

  

iOS开发系列课程(05) --- 导航视图控制器_导航条_05

设置背景图片

  • -setBackgroundImage:forBarMetrics:
  • -setBackgroundImage:forBarPosition:barMetrics:

说明:UIBarPostion和UIBarMetrics都是枚举类型,前者表示导航栏的位置;后者表示导航栏的外观。前者可能的取值包括:UIBarPositionAny(不指定位置)、UIBarPositionBottom(位于视图底部)、UIBarPositionTop(位于视图顶部)和UIBarPositionTopAttached(位于屏幕顶部同时也在其视图的顶部);后者可能的取值包括:UIBarMetricsDefault(设备默认的外观)、UIBarMetricsCompact(手机尺寸的外观)等。

隐藏和显示导航条

  • navigationBarHidden属性:是否隐藏导航控制栏

UINavigationItem

  通过视图控制器的navigationItem属性可以获得和视图控制器对应的导航栏项,该属性是只读的,但是通过它的子属性可以对UINavigationItem进行定制。可以定制的内容包括:

  • leftBarButtonItem/leftBarButtonItems属性:定制左侧导航项
  • rightBarButtonItem/rightBarButtonItems属性:定制右侧导航项
  • backBarButtonItem属性:定制返回项
  • title属性:导航项的标题
  • prompt属性:导航项的提示
  • titleView属性:导航项标题视图,该属性可以是任意UIView及其子类型,因此可以在此随意定制自己想要的东西

说明:由于navigationItem是每个视图持有自己的navigationItem,因此可以为每个视图定制不同的导航项。

  如果当前视图控制器通过navigationItem设置了leftBarButtonItem,则显示当前视图控制器设置好的leftBarButtonItem;如果当前视图控制器没有设置leftBarButtonItem,且当前视图控制器不是根视图控制器,显示上一层的backBarButtonItem;如果上一层没有指定backBarButtonItem,系统将根据上一层视图控制器的标题自动生成一个返回按钮;如果当前视图控制器没有设置leftBarButtonItem且当前视图控制器是根视图控制器,则左边不显示任何东西。

  如果当前视图控制器通过navigationItem属性定制了titleView,那么将会显示自定义的titleView,titleView的高度不应该超过导航条的高度;如果当前视图控制器没有定制titleView,系统会根据当前视图控制器的标题或者navigationItem的标题创建一个UILabel来显示此标题;navigationItem的标题优于视图控制器的标题。

强调:UINavigationController本身并不显示无需定制,UINavigationBar属于导航控制器(子对象),它使被多个视图共享的,当你切换视图控制器时,导航栏并没有切换,如果需要定制导航视图控制器就需要定制导航栏以及导航栏上的项目UINavigationItem。我们可以让每个视图控制器都有自己的UINavigationItem,并按照自己的意愿来创建它。

  下面通过代码对上述内容加以展示。

创建文字和图片UIBarButtonItem

// 重设rightBarButtonItem
    self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithImage:image style:UIBarButtonItemStyleDone target:self action:@selector(onClick:)];

    //重设leftBarButtonItem
    self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"itemImage1"] landscapeImagePhone:[UIImage imageNamed:@"itemImage2"] style:UIBarButtonItemStyleBordered target:nil action:nil];

创建系统自带的UIBarButtonSystemItem

UIBarButtonItem * item1 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCompose target:nil action:nil];
    UIBarButtonItem * item2 = [[UIBarButtonItem alloc] initWithTitle:@"OK" style:UIBarButtonItemStylePlain target:nil action:nil];

    // 使用自定义视图,创建barButtonItem
    UISwitch * sw = [[UISwitch alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];
    [sw addTarget:self action:@selector(pushNextViewController) forControlEvents:UIControlEventValueChanged];

    // barButton官方推荐大小是20*20
    UIBarButtonItem * item3 = [[UIBarButtonItem alloc] initWithCustomView:sw];

    // 将多个item添加到右侧
    self.navigationItem.rightBarButtonItems = @[item1, item2, item3];

定制backBarButtonItem

UIButton *goBackButton = [UIButton buttonWithType:UIButtonTypeSystem];
    goBackButton.frame = CGRectMake(10, 10, 60, 40);
    [goBackButton addTarget:self action:@selector(goBackButtonClicked) forControlEvents:UIControlEventTouchUpInside];
    [goBackButton setTitle:@"滚蛋" forState:UIControlStateNormal];
    UIBarButtonItem *barItem = [[UIBarButtonItem alloc] initWithCustomView:goBackButton];
    self.navigationItem.leftBarButtonItem = barItem;

UIToolbar

  每个导航控制器,还配备了工具条(44坐标高),默认隐藏,可以通过将导航视图控制器的toolBarHidden属性设置为NO使其显示。工具条属于UINavigationController,一个导航控制器,只有一个工具条。工具条上的toolBarItem属于每个视图控制器,每个视图控制器可以单独定制工具条上的每个项。

显示UINavigationController自带的UIToolbar

  • toolBarHidden属性:设置为NO可以显示自带的工具条

设置UIToolbar的背景图

self.navigationController.toolbarHidden = NO;
    UIImage *bgImage = [UIImage imageNamed:@"toolBar"];
    [navigationController.toolbar setBackgroundImage:bgImage forToolbarPosition:UIBarPositionBottom barMetrics:UIBarMetricsDefault];
    [self.navigationController.toolbar setTintColor:[UIColor whiteColor]];

向UIToolbar中增加UIBarButtonItem

UIBarButtonItem * item1 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:nil action:nil];
    UIBarButtonItem * item2 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemBookmarks target:nil action:nil];
    UIBarButtonItem * item3 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCamera target:nil action:nil];
    UIBarButtonItem * spaceItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
    self.toolbarItems = @[item1, spaceItem, item2, spaceItem, item3];

UIAppearance

UIAppearrance的作用

  从iOS 5开始,UIKit中提供了一个叫做UIAppearance的协议,通过该协议可以轻松的统一你的界面,它提供如下两个方法:

  • (id)appearance:通过它可以修改所有的指定类型的视图的UI
  • (id)appearanceWhenContainedIn:(Class <>)ContainerClass,…:可以指定要修改的类型包括哪些

修改导航样式

[[UIBarButtonItem appearanceWhenContainedIn:[UINavigationBar class], nil] setBackgroundImage:myNavBarButtonBackgroundImage forState:state barMetrics:metrics];
    [[UIBarButtonItem appearanceWhenContainedIn:[UINavigationBar class], [UIPopoverController class], nil] setBackgroundImage:myPopoverNavBarButtonBackgroundImage forState:state barMetrics:metrics];
    [[UIBarButtonItem appearanceWhenContainedIn:[UIToolbar class], nil]
        setBackgroundImage:myToolbarButtonBackgroundImage forState:state barMetrics:metrics];
    [[UIBarButtonItem appearanceWhenContainedIn:[UIToolbar class], [UIPopoverController class], nil] setBackgroundImage:myPopoverToolbarButtonBackgroundImage forState:state barMetrics:metrics];


标签:控制器,nil,05,iOS,视图,UIBarButtonItem,导航,属性
From: https://blog.51cto.com/u_16166070/6522338

相关文章

  • iOS开发系列课程(09) --- 滚动视图
    UIScrollView入门  移动设备的屏幕⼤小是极其有限的,因此直接展⽰在⽤户眼前的内容也相当有限,当展⽰的内容较多超出一个屏幕时,用户可通过滚动操作来查看屏幕以外的内容,普通的UIView不具备滚动功能,不能显⽰过多的内容。UIScrollView是一个能够滚动的视图控件,可以⽤用来展⽰大量的......
  • iOS开发笔记 - 用CocoaPods管理第三方库
    在iOS项目中使用第三方类库可以说是非常常见的事,但是要正确配置这些第三方库会非常的繁琐,还好我们有CocoaPods来做这件事情,就如同在Java的世界里有Maven和Gradle,当然Maven的作用不仅仅是第三依赖库管理。通过CocoaPods工具我们可以为项目添加被称为"Pods"的依赖库(这些类库必须是Coc......
  • iOS开发笔记 - App上架流程(视频分享)
    具体的文档可以看一下我的《iOS开发笔记-上线流程》iOS项目上线流程视频百度云盘分享下面是一些相关的官方文档:https://developer.apple.com/app-store/review/guidelines/-项目审核指南http://www.apple.com/legal/intellectual-property/guidelinesfor3rdparties.htmlhttps......
  • 6. SpringMVC的视图
    SpringMVC中的视图是View接口,视图的作用渲染数据,将模型Model中的数据展示给用户SpringMVC视图的种类很多,默认有转发视图和重定向视图当工程引入jstl的依赖,转发视图会自动转换为JstlView若使用的视图技术为Thymeleaf,在SpringMVC的配置文件中配置了Thymeleaf的视图......
  • FPGA电机控制源码(verilog+nios2架构)FPGA电机控制源码, 方案为单FPGA方案才用底层ver
    FPGA电机控制源码(verilog+nios2架构)FPGA电机控制源码,方案为单FPGA方案才用底层verilog+应用层nios2的软件架构,很具有学习价值。包括编码器模块算法,坐标变换算法,矢量调制算法等等。注:此代码不适合新手小白。FPGA电机控制源码是一个用于控制电机的程序代码,采用了FPGA(现场可......
  • [连载]JavaScript讲义(05)--- 数据处理
    ......
  • iOS开发系列课程预告
    最近在Mac和iOS上做开发,觉得应该写一点东西分享给感兴趣的童鞋们。在此之前,曾经有很多同行们都在埋怨苹果Objective-C的复杂和难以上手,为此也有很多人对今年(2014年)刚推出的Swift抱有很多幻想。首先在现阶段甚至五年以内,我个人感觉Mac和iOS的开发可以说仍然离不开Objective-C,即便是......
  • Palera1n越狱简体中文,iOS15.0~16.5越狱支持Mac/Linux/U盘多平台
    Palera1n越狱简体中文,iOS15.0~16.5越狱支持Mac/Linux/U盘多平台中文教程:https://dkxuanye.cn/?p=6813官方文档:https://github.com/palera1n/palera1n/releases......
  • 面试编程题拾遗(05) --- 括号匹配检查
    题目:一个表达式字符串中包含了‘(’,')','[',']','{','}'六种括号,判断这些括号是否匹配。解决这个问题可以使用一种叫“栈”的数据结构,它是一种FILO(先进后出)的结构,插入(push,入栈)和删除(pop,出栈)元素都是在栈顶进行。代码如下所示:importjava.util.Stack;publicclassTest05{ publicst......
  • [连载]C#程序设计(05)--- C#核心编程-3 --- 表达式和运算符
    ......