iOS学习笔记——多控制器管理

NavigationController

在StoryBoard中添加NavigationController 数组

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

TableViewController不是必要存在的,只是默认添加上去的,加入须要其余视图,则能够把它删除,从新拖入须要的视图,在NavigationController中按Ctrl键拖到新的视图中,这时弹出的Segue会比日常多了一项,它是属于RelationShip Segue分组的root view controller。工具

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

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

 

 

NavigationItem添加 3d

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

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则可。效果以下blog

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

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

加入TitleView的代码以下所示three

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以后相继触发的。

相关文章
相关标签/搜索