如何完美隐藏显示tabbar

243 views
Skip to first unread message

taoxiaoseng

unread,
Jun 30, 2013, 7:32:57 AM6/30/13
to iOSDe...@googlegroups.com
最近碰到了一个这样的问题,测试了好几种方式都没有完美解决掉隐藏显示tabbar的功能。

本来看微信能够完美在搜索栏目中搜索时全屏显示searchDisplayController里的那个tableview,我也想试试这个功能怎么做出来的。(打开微信在第一个tab或者第二个tab里点击搜索searchBar,然后随便搜索一下,显示出来的列表能完全占满整个屏幕)。但我测试了下标准的searchDisplayController只能覆盖到tabbar的上方,不能全屏显示。

下面是我的测试过程:

=======
这里先定义下一个vc的代号,
当前vc为vcA,push的页面vc为vcC,点击搜索功能进入searchDisplayController的页面这里暂且较为vcB
=======

状况1:
我尝试在这个searchDisplayController 开始search的时候隐藏tabbar,然后在消失的时候显示tabbar,结果tabbar是隐藏了,新的问题出现了。

因为我push一个view controller C,后面的viewcontrollerC是一个全屏的,也就是说我在viewcontrollerC里初始化代码里加入了

        self.hidesBottomBarWhenPushed = YES;

这样我是希望在push时,下一个页面永远保持全屏状态。

结果实际上的效果是,我进入searchDisplayController后,点击一个cell进入下一个页面(这个时候还是正常,前一个页面是全屏,后一个页面也是全屏),但是在页面返回的时候,tabbar又重新显示出来了。。。。悲剧!)。(可以下载附件里的代码,在FirstViewController里注释掉TheSecondSolution宏定义,查看这个时候的效果及问题


状况2:

于是我捉摸可能是因为当前的页面(第一个页面)的hidesBottomBarWhenPushed为NO,于是当页面返回时,检查到需要显示的top viewcontroller是一个希望显示tabbar的页面,于是ios内部开始计算,重新排版显示tabbar,于是tabbar又显示出来了!!


于是我再次尝试在进入searchDisplayController显示点击tableviewcell的时候,我修改了self.hidesBottomBarWhenPushed = YES;

并且在隐藏searchDisplayController时重新修改self.hidesBottomBarWhenPushed = NO;

结果我在searchDisplayController显示时点击tableviewcell进入下一个页面,然后返回,这些操作都变的正常了。但是新的问题又出来了.


在我进行如上操作后,在正常的页面里(searchDisplayController隐藏时,当前view controller里的那个tableview里)点击cell,进入下一个页面,结果下面的tab bar不隐藏了。。。。这个时候的状态时vcA的hidesBottomBarWhenPushed为NO,vcC当然永远为YES,但是这个时候push动作确实不会隐藏tabbar。

(可以下载附件里的代码,在FirstViewController里打开TheSecondSolution宏定义,查看这个时候的效果及问题)


我尝试了很多方法,没有真正的像微信那样唯美的显示。所以请求下各位有谁知道到底如何完美的隐藏tabbar(可以动态修改当前页面的tabbar的隐藏和显示,并且在下一个页面是全屏显示的时候,能在进入或者返回时能完全的控制住这个tabbar的显示隐藏)。


下面是我的猜测,

1:UITabBarController里有个私有成员变量unsigned int isBarHidden:1;通过私有API

-(BOOL)_isBarHidden;访问到这个值,我自己去隐藏显示tabbar的时候,这个私有成员的变量的值是不会变化。当我进入searchDisplayController并且修改过self.hidesBottomBarWhenPushed = YES,然后从下个页面返回到当前页面时,我的tabbar是隐藏的,tabbarcontroller里私有api _isBarHidden获取到的值为YES,即使你再次修改了hidesBottomBarWhenPushed为NO,tabbarController里的这个表示变量仍然是YES,我改变不了他,那么当我重新显示出tabbar的时候,点击tableview cell进入vcC时,可能iOS发现下一个页面hidesBottomBarWhenPushed为YES,而当前tabbarcontroller的tabbar是隐藏的,那么系统可能就认为没有必要再次调整tab bar的x坐标为-320(正常状态下前一个页面有tab bar,后一个页面没有时,系统会在动画过程中将tab bar隐藏到x坐标为-320的地方)。于是tab bar就不能正常的隐藏了,即使设置了topviewcontroller的hidesBottomBarWhenPushed的值为YES。


2:我猜测hidesBottomBarWhenPushed这个值你可以随意修改,但是他仅仅是一个变量表示一个view controller的hidesBottomBarWhenPushed属性,并且在navigationcontronller在push或者pop时,会根据下一个topviewcontroller的hidesBottomBarWhenPushed的值和当前tabbar显示的状态,去判断是否需要重新调整tabbar的位置。



不知道各位有没有这方面的经验,能很好的控制显示隐藏tabbar,并且又不会因为系统的调整而出现一些问题?


附件里是我测试的工程
大家跑起工程后,可以不断的点击cell进入下一个页面和返回前一个页面,以及点击出displaysearchcontroller后点击cell进入下一个页面和返回来。尝试是否能模拟出微信的那种交互来检查。

【注意】工程里引入了上次tangqiao有篇文章里说的Reveal,去查看各个界面层级。如果大家用过的,可以直接用,如果因为这个跑不起来,可以移除掉(other linker flag里还有个linker flag),可以看到有UITransitionView和TabBar去真正控制tabbarcontroller的布局。

-- 

Sent with Sparrow

tt.zip

Felix Dong

unread,
Jul 2, 2013, 10:00:20 AM7/2/13
to iOSDe...@googlegroups.com
Reveal给个链接?我想看看

Felix Dong

unread,
Jul 2, 2013, 11:44:47 AM7/2/13
to iOSDe...@googlegroups.com
看下我附件,我觉得应该是完美解决了。第一次知道有searchDisplayController和hidesBottomBarWhenPushed,又学到了新东西。。。
tt2.zip

Felix Dong

unread,
Jul 3, 2013, 7:42:49 AM7/3/13
to iOSDe...@googlegroups.com
我的错,在公司下载代码后发现还是原来的代码,误将原来的zip重命名了,再重新上传一遍吧。btw.如果这代码在github上就没这问题了
事实证明,写代码不能写得太晚
tt2.zip

小浪花

unread,
Aug 3, 2013, 12:33:08 PM8/3/13
to iOSDe...@googlegroups.com
我是这样解决的,我觉得还是完美的。。。 
//setTabBarHidden
-(void)setTabBarHidden:(BOOL)bol{
    AppDelegate *appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
    UITabBarController *tabBar = appDelegate.tbarController;
    ////隐藏
    if(bol == YES){
        [tabBar.view setFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT+50)];
        NSArray *views = [tabBar.view subviews];
        for(id v in views){
            if([v isKindOfClass:[UITabBar class]]){
                [(UITabBar *)v setHidden:YES];
            }
        }
    }else {//显示
        [tabBar.view  setFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)];
        NSArray *views = [tabBar.view subviews];
        for(id v in views){
            if([v isKindOfClass:[UITabBar class]]){
                [(UITabBar *)v setHidden:NO];
            }
        }
    }
}

On Sunday, June 30, 2013 7:32:57 PM UTC+8, taoxiaoseng wrote:

zhao guang

unread,
Aug 6, 2013, 4:00:05 AM8/6/13
to 小浪花, iOSDe...@googlegroups.com
我是重写了一个tabbarViewController的子类 然后这样实现下

- (void)showTabBar:(BOOL)show
{
    if (show != self.tabBar.hidden)
        return;
    
    UIView* subview= [self.view.subviews objectAtIndex:0];
    CGRect frame = subview.frame;
    CGRect tabBarFrame =self.tabBar.frame;
    if (show) {
        frame.size.height -= self.tabBar.frame.size.height;
        tabBarFrame.origin.y -= self.tabBar.frame.size.height;
    } else {
        frame.size.height += self.tabBar.frame.size.height;
        tabBarFrame.origin.y += self.tabBar.frame.size.height;
    }
    subview.frame = frame;
    self.tabBar.frame = tabBarFrame;
    self.tabBar.hidden = !show;
}

--
您收到此邮件是因为您订阅了 Google 网上论坛的“iOS开发”论坛。
要退订此论坛并停止接收此论坛的电子邮件,请发送电子邮件到 iOSDevTips+...@googlegroups.com
要向此网上论坛发帖,请发送电子邮件至 iOSDe...@googlegroups.com
通过以下网址访问此论坛:http://groups.google.com/group/iOSDevTips。
要在网络上查看此讨论,请访问 https://groups.google.com/d/msgid/iOSDevTips/d61e9723-c949-4f16-a613-badef847cbd0%40googlegroups.com。
要查看更多选项,请访问 https://groups.google.com/groups/opt_out。
 
 

Allen Cao

unread,
Aug 15, 2016, 3:04:56 AM8/15/16
to iOS开发
楼主解决了了吗,现在也在做这个。。

在 2013年6月30日星期日 UTC+8下午7:32:57,taoxiaoseng写道:
Reply all
Reply to author
Forward
0 new messages