zoukankan      html  css  js  c++  java
  • iOS学习笔记——多控制器管理

    NavigationController

    在StoryBoard中添加NavigationController

    在上网看到很多都是用xib添加,使用StoryBard的有两种办法,但我觉得下面用到那种方式比较好,直接在StoryBard中拖入一个NavigationController,在StoryBard中出现两个视图,一个是NavigationController,另一个是TableViewController。

    TableViewController不是必要存在的,只是默认添加上去的,加入需要其他视图,则可以把它删除,重新拖入需要的视图,在NavigationController中按Ctrl键拖到新的视图中,这时弹出的Segue会比平常多了一项,它是属于RelationShip Segue分组的root view controller。

    使用该Segue后,会发现第二个视图中出现了导航栏。把示意app启动引导的那个箭头拉到第一个视图,也就是NavigationController前面,

    启动app会发现,app启动并非引导到NavigationController,而是后来新加的那个视图。在启动后打开的那个页面的导航栏中修改Title属性为"首页",那么往后我们也称这个页面为"首页",再往StoryBoard上面拖一个新的视图,在"首页"中添加一个Button按钮,给Button和新的页面建立Segue,类型选择为push,这个类型与往常用的Modal不一样,使用后原本空白的页面上多了导航栏和工具栏,然后在这个页面的导航栏中修改Title属性为"次页",保存运行一下,当点击Button跳转到次页的时候,发现导航栏多了一个后退的按钮,按钮上的文字也写明是"首页",故名思意就知道点击该按钮就能返回到"首页"了

    NavigationItem添加

    上面提到的后退按钮,其实是导航栏上面的一种导航栏元素,对于一个导航栏它会有LeftBarItem、RightBarItem、TitleView还有一个比较特殊的位于导航栏左边的BackBarItem。经本人尝试,如果一个导航栏上有BackBarItem和LeftBarItem,那么BackBarItem会被LeftBarItem覆盖,但这个有可能是本人尝试的范围有点窄,涵盖不了所有情况,按本人推断有可能是最后一个加到导航栏的就显示到导航栏上。那下面就演示一下单纯在导航栏上添加NavagationItem。

    UIBarButtonItem *leftButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:@selector(selectLeftAction:)];
    
    self.navigationItem.leftBarButtonItem = leftButton;
    
     
    
     
    
    UIBarButtonItem *rightButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(selectRightAction:)];
    
    self.navigationItem.rightBarButtonItem = rightButton;

    在上述代码中添加了左部按钮和右部按钮,两个按钮都被绑定了点击事件,调用不同的方法,如果点击后无操作则传入nil则可。效果如下

    两个按钮的图标有所差别,这个在初始化方法的第一个参数所控制,其他值和图片分别如下表所示

    • UIBarButtonSystemItemAdd
    • UIBarButtonSystemItemCompose
    • UIBarButtonSystemItemReply
    • UIBarButtonSystemItemAction
    • UIBarButtonSystemItemOrganize
    • UIBarButtonSystemItemBookmarks
    • UIBarButtonSystemItemSearch
    • UIBarButtonSystemItemRefresh
    • UIBarButtonSystemItemStop
    • UIBarButtonSystemItemCamera
    • UIBarButtonSystemItemTrash
    • UIBarButtonSystemItemPlay
    • UIBarButtonSystemItemPause
    • UIBarButtonSystemItemRewind
    • UIBarButtonSystemItemFastForward
    • UIBarButtonSystemItemUndo
    • UIBarButtonSystemItemRedo

    加入TitleView的代码如下所示

    NSArray *array = [NSArray arrayWithObjects:@"元素1",@"元素2", nil];
    
    UISegmentedControl *segmentedController = [[UISegmentedControl alloc] initWithItems:array];
    
    segmentedController.segmentedControlStyle = UISegmentedControlSegmentCenter;
    
     
    
    [segmentedController addTarget:self action:@selector(segmentAction:) forControlEvents:UIControlEventValueChanged];
    
    self.navigationItem.titleView = segmentedController;
    
     

    这样程序运行起来就有一个分段控件在标题处

    因为返回按钮是选择了push类型的Segue而自动生成的,而按钮上的文字都是自动添加上去的,加入要给这个按钮进行修改设置,单纯构造一个UIBarButtonItem赋值到self.navigationItem.backBarButtonItem属性上是不行的。因为这个self.navigationItem.backBarButtonItem并非本页面的返回按钮,实际是以本页面为起始页而导航到的下一页的返回按钮。引用一个网友的说法就是比如在AController跳转到BController,在A设置了self.navigationItem.backBarButtonItem,这个backBarButtonItem为BController的self.navigationController.navigationBar.backItem.backBarButtonItem。那么在要设置这个返回按钮则需要在HGNaviView1Controller中添加以下代码

    UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@"根视图" style:UIBarButtonItemStyleDone target:self action:@selector(On_BackButton_Click)];
    
     
    
    [self.navigationItem setBackBarButtonItem:backButton];

    效果则如下图

    在NavicationController中有两个属性是设置Bar Visibility,一个是设置导航栏的可视性;另一个设置工具栏的可视性。

    同样也可以通过代码设置

    [self.navigationController setToolbarHidden:false animated:true];

    通过上面两种方式设置的结果都是全局的,凡是跟同一个NavigationController建立Segue的视图都会受影响。往工具栏上面添加按钮类似在导航栏上添加按钮,都是使用UIBarButtonItem,但添加到工具栏时是通过一个数组,代码如下所示

    UIBarButtonItem *one = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:nil action:nil];
    
    UIBarButtonItem *two = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemBookmarks target:nil action:nil];
    
    UIBarButtonItem *three = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:nil action:nil];
    
    UIBarButtonItem *four = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit target:nil action:nil];
    
    UIBarButtonItem *flexItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
    
     
    
    [self setToolbarItems:[NSArray arrayWithObjects:flexItem, one, flexItem, two, flexItem, three, flexItem, four, flexItem, nil]];

    当然ToolBar可以自行添加,但如果不把NavigationController统一建立的工具栏隐藏掉的话会导致视图上会有两个工具栏,假如只是个别页面需要显示工具栏的话个人还是觉得把NavigationController统一建立的工具栏隐藏,在需要的界面中自行添加工具栏

    [self.navigationController setToolbarHidden:true animated:true];
    
    UIBarButtonItem *one = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:nil action:nil];
    
    UIBarButtonItem *two = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemBookmarks target:nil action:nil];
    
    UIBarButtonItem *three = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:nil action:nil];
    
    UIBarButtonItem *four = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit target:nil action:nil];
    
    UIBarButtonItem *flexItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
    
     
    
    UIToolbar *toolBar = [[UIToolbar alloc] initWithFrame:CGRectMake(0.0, self.view.frame.size.height - 44.0, self.view.frame.size.width, 44.0)];
    
    [toolBar setBarStyle:UIBarStyleDefault];
    
    toolBar.autoresizingMask = UIViewAutoresizingFlexibleTopMargin;
    
    [toolBar setItems:[NSArray arrayWithObjects: flexItem, one, flexItem, two, flexItem, three, flexItem, four, flexItem,nil]];
    
    [self.view addSubview:toolBar];

    效果和上图完全一样

    TabBarController

    TabBarController使用

    在使用过NavigationController之后使用TabBarController就容易上手了,在StoryBoard中拖入TabBarController,情况与NavigationController的类似,第一个页面TabBarController并非会呈现到用户界面中去,它只是起到一个管理各个子页面的效果,每个选项卡的具体内容会在他们的视图中编辑,这里默认会建立两个Tab,

    如果需要再多的Tab,就可以直接拖入对应的ViewController,在TabBarController页面按Ctrl连接到新页面建立Segue,这里的Segue类型又有不同,Relationship Segue分组中有一个view controllers,就选择那个可以了,这样在TabBarController中会多加了一个Tab。

    Tab修改

    每个Tab的图标和文字都可以在相应的Tab视图中修改,

    图标的尺寸是有限制的,在30*30,如果过大了就会有部分显示不出来,而且就算是给的图标是一个彩色的图片,最终显示在界面上的都只剩下一个轮廓,原图与显示在TabBar中的对比

    在代码中同样可以用相应的属性对Tab的标题和图片进行设置

    [self.tabBarItem setImage:[UIImage imageNamed:@"SunFlower.gif"]];
    
    [self.tabBarItem setTitle:@"第一选项卡"];

    不过有另一个方法setFinishedSelectedImage:withFinishedUnselectedImage则可以把图标完整显示出来,如果图标过大则会占用下面文字的空间,而且图标会按原本的颜色显示出来,图标的显示还会按照选项卡的选中状态来决定

    [self.tabBarItem setFinishedSelectedImage:[UIImage imageNamed:@"SunFlower.gif"] withFinishedUnselectedImage:[UIImage imageNamed:@"Ixia.gif"]];

    选中时

    未选中时

    在每个TabBarItem中都有一个badgeValue属性,用于设置Tab的小红圈的值,他是NSString,所以可以给他赋的值就不局限在数字,还可是其他字符

    self.tabBarItem.badgeValue=@"new";

    Tab的数量可以无限地增加,但是在节目是最多可以显示五个Tab标签,如果Tab的数量多于5个的时候,原本第5个的Tab就会变成,并且点击进去是一个带TableView的导航页,从第5个开始的Tab会在TableView中显示,从TableView中导航到的Tab页都会带导航栏,以返回TabeView那一页

    导航栏上面还有编辑按钮进入配置Tab的页面

    在这一页中可以拖拽各个Tab标签到底部的TabBar中以更改Tab在TabBar中的顺序,而这里显示的Tab是可以通过UITabBarController的customizableViewControllers属性设定的,默认情况下它是和UITabBarController的viewController属性(这个就是UITabBarController拥有Tab的集合)拥有相同的元素,但是也可以通过设置把第6个Tab从customizableViewControllers中去除

    NSArray *viewControllers= self.tabBarController.viewControllers;
    
    NSMutableArray *newViewControllers=[NSMutableArray arrayWithCapacity:viewControllers.count-1];
    
    for (int i=0; i<[viewControllers count]-1; i++) {
    
        [newViewControllers addObject:[viewControllers objectAtIndex:i]];
    
    }
    
    self.tabBarController.customizableViewControllers=newViewControllers;

    结果第6个Tab就不会出现在Configure页面中了

    而对于viewControllers有的Tab而customizableViewControllers没有的Tab,则该部分Tab在编辑状态下不会被移除出TabBar。

    关于选中的Tab

    通过selectedIndex和selectedViewController都可以获取或设置被选中的Tab,对于设置selectedIndex和selectedViewController而言,仅仅能设置可以选中的Tab,并不能把页面切换过去,而且对于More这个Tab来说还有点特别的情况

    • 选中了More,selectedIndex是不能获取其准确的索引值,而selectedViewController可以获取到它的UITabBarItem;
    • 如果对selectedIndex赋上大于等于5的值,Tab就会选中More;
    • 如果对selectedViewController赋上tabBarController.moreNavigationController或者索引值大于或等于5的UITatBarItem,Tab就会选中More

    UITabBarController的tabBar属性里面也可以通过selectedItem获取选中的UITabBarItem,但是并不能给这个selectedItem赋值,这回引发异常。虽然UITabBar有一些方法是可以改变自身状态,但不能给UITabBarController的tabBar修改自身状态。

    UITabBarController的事件

    UITabBarController拥有一些事件,通过这些事件可以监测Tab发生变化,这需要给ViewController实现UITabBarControllerDelegate协议,然后设置tabBarController的delegate属性

    self.tabBarController.delegate=self;

    事件归为两类,一类是单纯tabBar上Tab的选中状态发生变更前后出发的

    -(BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
    
     
    
    -(void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController

     

    先触发前者再触发后者,前者有一个布尔类型的返回值,如果返回的是False则会取消Tab的切换,但是通过代码设置SelectedIndex除外。两个参数tabBarController代表着起始的TabviewController代表着目标的Tab

    另一类是针对moreViewControlleredit操作的

    -(void)tabBarController:(UITabBarController *)tabBarController willBeginCustomizingViewControllers:(NSArray *)viewControllers
    
     
    
    -(void)tabBarController:(UITabBarController *)tabBarController willEndCustomizingViewControllers:(NSArray *)viewControllers changed:(BOOL)changed
    
     
    
    -(void)tabBarController:(UITabBarController *)tabBarController didEndCustomizingViewControllers:(NSArray *)viewControllers changed:(BOOL)changed 

    WillBegin…是在进入Edit界面时触发的,WillEnd…didEnd….是在点击了Done之后相继触发的。

  • 相关阅读:
    DUILib的代码分析
    source$表坏块
    树莓派风扇自动控制随想
    给qq机器人加上bing搜索
    龙芯fedora28日常生存指南
    攻防世界 when_did_you_born
    部署PWN题Docker环境
    NPUCTF2020 EzRSA
    金融密码杯 The Art of War
    Machine Learning & Deep Learning Fundamentals
  • 原文地址:https://www.cnblogs.com/HopeGi/p/4401398.html
Copyright © 2011-2022 走看看