IOS app中有两个UITabBarController,即在第一个页面有4个按钮,进入子页面底部也有几个按钮
ios app中有两个uitabbarcontroller,即在第一个页面有4个按钮,进入子页面底部也有几个按钮。对于一个app中有两个tabbar,大部分 认为该ui不够友好,也不符合苹果的人机交互。
我们先看下效果图
事实上我们有两种解决方案
1.在子页面底部的tabbar我们可以用按钮代替,跟之前博客说在导航栏上uisegmentedcontrol,切换显示不同的vc,
2、在app中添加2个tabbar。
方案1,在此不再赘述,可参考之前的那片博客,直接看下方案2
1)、新建一个vc继承uitabbarcontroller,然后在该vc中初始化tabbar
/* 初始化tabbar */ - (void)inittabbar{ homeoneviewcontroller *h1 = [[homeoneviewcontroller alloc] init]; hometwoviewcontroller *h2 = [[hometwoviewcontroller alloc] init]; homethreeviewcontroller *h3 = [[homethreeviewcontroller alloc] init]; homefourviewcontroller *h4 = [[homefourviewcontroller alloc] init]; nsarray *rootarray = [nsarray arraywithobjects:h1,h2,h3,h4, nil]; nsarray *namearray = [nsarray arraywithobjects:@"首页",@"签到",@"日报",@"我的", nil]; h1.title = namearray[0]; h2.title = namearray[1]; h3.title = namearray[2]; h4.title = namearray[3]; nsmutablearray *vcarray = [nsmutablearray array]; for (int index = 0; index < rootarray.count; index++) { uinavigationcontroller *nav = [[uinavigationcontroller alloc] initwithrootviewcontroller:rootarray[index]]; //tabbar未选中的image uiimage *normalimg = [[uiimage imagenamed:[nsstring stringwithformat:@"tabbar%d_no.png",index + 1]] imagewithrenderingmode:uiimagerenderingmodealwaysoriginal]; //tabbar已选中的image uiimage *selectimg = [[uiimage imagenamed:[nsstring stringwithformat:@"tabbar%d_yes.png",index+1]] imagewithrenderingmode:uiimagerenderingmodealwaysoriginal]; //设置tabbar显示的文字 nav.tabbaritem = [[uitabbaritem alloc] initwithtitle:namearray[index] image:normalimg selectedimage:selectimg]; nav.tabbaritem.tag = index +1; nav.tabbaritem.title = namearray[index]; [vcarray addobject:nav]; } //tabbar未选中时文字的颜色,字体大小 [[uitabbaritem appearance] settitletextattributes:[nsdictionary dictionarywithobjectsandkeys:[uicolor lightgraycolor],nsforegroundcolorattributename,[uifont systemfontofsize:14.0],nsfontattributename, nil] forstate:uicontrolstatenormal]; [[uitabbaritem appearance] settitletextattributes:[nsdictionary dictionarywithobjectsandkeys:rcolor,nsforegroundcolorattributename,[uifont systemfontofsize:14.0],nsfontattributename, nil] forstate:uicontrolstateselected]; self.viewcontrollers = vcarray; self.view.backgroundcolor = [uicolor whitecolor]; }
2)、我们在homeoneviewcontroller中的cell点击事件中添加如下代码,即进入第二个tabbar
-(void)tableview:(uitableview *)tableview didselectrowatindexpath:(nsindexpath *)indexpath{ flag = 0; onesubviewcontroller *ycf = [[onesubviewcontroller alloc] init]; ycf.hidesbottombarwhenpushed=yes;// 进入后隐藏tabbar [self.navigationcontroller pushviewcontroller:ycf animated:yes]; }
3)、onesubviewcontroller就是第二个tabbar,也是继承自uitabbarcontroller,里面初始化tabbar 方式一样。代码不再贴了
然后运行代码后就会发现一个问题suboneviewcontroller和subtwoviewcontroller有两个导航条,因为在第一个tabbar有导航条,第二个tabbar也有。看下上面的代码中有flag,看下作用,就是是否需要隐藏第一个tabbar的navigationcontroller,在进入第二个tabbar是需要隐藏,
- (void)viewwillappear:(bool)animated{ [super viewwillappear:animated]; self.navigationcontroller.navigationbar.hidden= no; } - (void)viewwilldisappear:(bool)animated{ [super viewwilldisappear:animated]; if (flag==0) { self.navigationcontroller.navigationbar.hidden= yes; } }
4)、现在看下返回按钮的事件,一搬的子页面回到父vc,直接
[self.navigationcontroller popviewcontrolleranimated:yes];
但是在第二个tabbar回到上个tabbar,该如何回去呢,如下方式才能回去
[self.tabbarcontroller.navigationcontroller popviewcontrolleranimated:yes];
需要注意的是我这边的子vc都继承了一个baseviewcontroller,里面有对导航栏和页面样式的配置。
self.navigationcontroller.navigationbar.translucent = no;//1、导航栏不模糊,2、view的高度从导航栏底部开始 self.edgesforextendedlayout = uirectedgenone;//指定边缘要延伸的方向,它的默认值很自然地是uirectedgeall,四周边缘均延伸,就是说,如果即使视图中上有navigationbar,下有tabbar,那么视图仍会延伸覆盖到四周的区域。将属性设置为uirectedgenone 被上面两个属性坑死了 self.extendedlayoutincludesopaquebars = no; self.modalpresentationcapturesstatusbarappearance = no;
写这个demo时,我没有设置self.edgesforextendedlayout,默认值时uirectedgeall,底部tabor会遮挡子vc的底部49高度。仅此谨记!!!
对于这个2个tabbar还有中实现方式,在appdelegate中,先初始化2个tabbar,默认rootviewcontrooler = 第一个tabbar。在点击cell跳转到第二个tabbar时,再将rootviewcontrooler=第二个tabbar,从第二个tabbar回到第一个tabbar时,也是重新设置rootviewcontrooler。