【问题标题】:Tap to toggle fullscreen - issues with opaque tabBar点击以切换全屏 - 不透明 tabBar 的问题
【发布时间】:2014-09-27 18:03:15
【问题描述】:

我正在尝试通过将 statusBar、navigationBar 和 tabBar 隐藏在一起,使我的应用在用户点击时在单个视图中“全屏”。

我可以很好地隐藏和显示导航栏和状态栏,但是在隐藏 tabBar 时我遇到了一些问题。

这是隐藏之前的样子:

这是隐藏后的:

隐藏时,tabBar 会留下一个空白点,我试图隐藏但没有成功。

这是我目前正在使用的代码

-(void)toggleBars:(UITapGestureRecognizer *)gesture{
    //Hide navigationBar    
    BOOL toggleNavigationBar = self.navigationController.navigationBarHidden;
   [self.navigationController setNavigationBarHidden:!toggleNavigationBar animated:YES];


    //Hide tabBar - not hiding, leaving a black spot
    BOOL toggleTabHidden = self.tabBarController.tabBar.hidden;
    [self.tabBarController setTabBarHidden:!toggleTabHidden];

    //Hide statusBar
    BOOL statusBarHidden = [UIApplication sharedApplication].statusBarHidden;
    [[UIApplication sharedApplication] setStatusBarHidden:!statusBarHidden withAnimation:UIStatusBarAnimationSlide];
    if ([self respondsToSelector:@selector(setNeedsStatusBarAppearanceUpdate){
        [self setNeedsStatusBarAppearanceUpdate];
    }
}

我用谷歌搜索了很多,甚至在 SO 上查找了这里,但我没有找到任何可以帮助我的东西。

从视觉上看,这就是我想要实现的目标

----------------                  --------------
|navBar &statbar|                |              |  
|---------------                 |              |
|               |      tap       |              | 
|   content     |     ----->     | content only |         
|               |                |in fullscreen |
|               |                |              |
|-------------- |                |              |
|    tabbar     |                |              |
 -------------                    --------------

TL;DR

我想让我的应用在点击时全屏显示,我想知道如何删除 tabBar 在隐藏时留下的空白点。

提前致谢。

编辑 1

我在this question 中关注了Sebastian Keller 的回答,空白的tabBar 现在被隐藏了,但是动画有点大车而且不流畅。

编辑 2

创建一个虚拟项目后,我重新制作了 Storyboard,我注意到问题在于,当 tabBar 设置为不透明时,它会留下空白栏。这在设置为半透明时不适用。

这是dummy project to demonstrate the issue

【问题讨论】:

  • 您在使用自动布局吗?我想我可能会为您提供解决方案。
  • 是的,我正在使用自动布局。

标签: ios objective-c uitabbar


【解决方案1】:

这就是我遇到那个黑条时的解决方法。动画应该很流畅。 此代码使用您可以在此处找到的出色的 FrameAccessor 类:https://github.com/AlexDenisov/FrameAccessor

所以不要这样:

CGRect newFrame = view.frame;
newFrame.origin.x = 15;
view.frame = newFrame;

我们可以这样做:

view.x = 15;

这会容易得多。子类化 UITabBar 控制器并在您的 UITabBar 控制器自定义类中选择它。

SSTabBarController.h:

#import <UIKit/UIKit.h>

@interface SSTabBarController : UITabBarController
@property (assign) BOOL isTabBarOpen;

-(void)showOrHideTabBar;
- (void)hideTabBarWithAnimation:(BOOL)animated;
- (void)showTabBarWithAnimation:(BOOL)animated;

@end

SSTabBarController.m:

#import "SSTabBarController.h"
#import "FrameAccessor.h"

#define IPHONE_HEIGHT [[UIScreen mainScreen] bounds].size.height
#define TABBAR_HEIGHT 49

@interface SSTabBarController ()

@end

@implementation SSTabBarController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}


- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

}
- (void)viewDidLoad
{
    [super viewDidLoad];
     //This part is optional. If you are using opaque tabbar you can mark extend edged in your `StoryBoard`.
        /*UIView *tabBarBackround = [[UIView alloc]initWithFrame:CGRectMake(0, [UIScreen          mainScreen].bounds.size.height-TABBAR_HEIGHT, 320, TABBAR_HEIGHT)];
    tabBarBackround.backgroundColor =[UIColor colorWithRed:236/255.0 green:236/255.0 blue:236/255.0 alpha:1];
    [self.view addSubview:tabBarBackround];
    [self.view insertSubview:self.tabBar aboveSubview:tabBarBackround];*/

}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

-(void)showOrHideTabBar
{
    if(_isTabBarOpen)
    {
        [self hideTabBarWithAnimation:YES];
    }
    else
    {
        [self showTabBarWithAnimation:YES];
    }
}

- (void)showTabBarWithAnimation:(BOOL)animated
{
    _isTabBarOpen = YES;
    for(UIView *view in self.view.subviews)
    {
        if([view isKindOfClass:[UITabBar class]])
        {
             if(animated)
             {
                 [UIView animateWithDuration:0.4 animations:^()
                  {
                      view.y = IPHONE_HEIGHT - view.height;
                  }
                                  completion:^(BOOL finished){}];
             }
            else
            {
                view.y = IPHONE_HEIGHT - view.height;
            }
        }
    }
}

- (void)hideTabBarWithAnimation:(BOOL)animated
{
    _isTabBarOpen = NO;
    for(UIView *view in self.view.subviews)
    {
        if([view isKindOfClass:[UITabBar class]])
        {
             if(animated)
             {
                 [UIView animateWithDuration:0.4 animations:^()
                  {
                      view.y = IPHONE_HEIGHT;
                  }
                                  completion:^(BOOL finished){}];
             }
            else
            {
                view.y = IPHONE_HEIGHT;
            }
        }
    }
}
@end

在任何其他ViewController:

- (IBAction)hideTabbar:(UIButton *)sender
{

    SSTabBarController *myTabBar = (SSTabBarController*)self.tabBarController;
    [myTabBar showOrHideTabBar];
}

如果您使用 opaque,请确保在您的 UITabBarController 和您的 ViewController 中签入:

这是一个可以下载的工作项目: http://bit.ly/10fSxkU

【讨论】:

  • 什么是 IPHONE_HEIGHT 常数?
  • 好吧,iPhone 高度 :)。编辑了我的答案
  • 是啊猜对了,所以哈哈无论如何 view.y 会产生错误。不应该是 view.frame.origin.y 之类的吗?
  • 是的,很抱歉。我正在使用一个很棒的名为 FrameAccessor 的类来解决这个问题,强烈推荐。 github.com/AlexDenisov
  • 不幸的是没有运气。栏甚至不动
【解决方案2】:

我更喜欢隐藏标签栏,而不是通过向下拉伸 UITabBarController.view 来将其 tabBar 移出屏幕:

- (void)setTabBarHidden:(BOOL)hidden
{
    CGRect frame = self.originalViewFrame;
    if (hidden)
    {
        frame.size.height += self.tabBar.size.height;
    }
    self.view.frame = frame;
}

这会自动很好地拉伸包含的控制器的视图。

代码here

【讨论】:

    【解决方案3】:

    我最终使用了the answer I've linked 中建议的方法。通过一些调整,它正在工作。

    【讨论】:

    • 我认为调用layoutSubviews 是关键
    【解决方案4】:

    使用以下代码,几乎与您自己的相同,我可以毫无问题地重现您想要的效果:

    - (void)viewDidLoad {
        [super viewDidLoad];
    
        UITapGestureRecognizer *tapGR = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(toggleBars)];
        [self.view addGestureRecognizer:tapGR];
    }
    
    - (void)toggleBars {
        BOOL toggleNavigationBar = self.navigationController.navigationBarHidden;
        [self.navigationController setNavigationBarHidden:!toggleNavigationBar animated:YES];
    
        BOOL toggleTabHidden = self.tabBarController.tabBar.hidden;
        [self.tabBarController.tabBar setHidden:!toggleTabHidden];
    
        BOOL statusBarHidden = [UIApplication sharedApplication].statusBarHidden;
        [[UIApplication sharedApplication] setStatusBarHidden:!statusBarHidden withAnimation:UIStatusBarAnimationSlide];
        if ([self respondsToSelector:@selector(setNeedsStatusBarAppearanceUpdate)]) {
            [self setNeedsStatusBarAppearanceUpdate];
        }
    }
    

    视频演示: https://www.dropbox.com/s/5vzgfxc5f043lxy/hide.mov?dl=0

    【讨论】:

    • 我试过了,但不幸的是,空白栏不断弹出:(
    猜你喜欢
    • 2014-01-25
    • 2014-08-08
    • 1970-01-01
    • 1970-01-01
    • 2019-06-05
    • 1970-01-01
    • 1970-01-01
    • 2011-05-24
    • 2012-12-08
    相关资源
    最近更新 更多