如何防止状态栏与UINavigationController上设置的hidesBarsOnSwipe重叠内容?

Mic*_*uba 34 objective-c uinavigationbar uinavigationcontroller ios ios8

我正在尝试使用iOS 8中添加的新功能 - 在用户滚动表格视图时隐藏导航栏(类似于移动Safari的功能).我设置的财产hidesBarsOnSwipeUINavigationController,以YESviewDidAppear的方法UITableViewController:

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    if([self.navigationController respondsToSelector:@selector(hidesBarsOnSwipe)]) {
        self.navigationController.hidesBarsOnSwipe = YES;
    }
}
Run Code Online (Sandbox Code Playgroud)

滚动视图时,导航栏会隐藏.到现在为止还挺好.但状态栏仍然可见,我的表视图内容通过它显示,看起来很丑:

在此输入图像描述

我试着设置edgesForExtendedLayoutUIEdgeRectNone或调节contentInset表视图,但它并没有帮助.是否有任何其他解决方案可以隐藏状态栏和导航栏,或使其不透明?

iOS*_*gey 39

实际上这很容易做到.您只需要将导航isNavigationBarHidden属性与状态栏连接起来.

Objective-C的

- (BOOL)prefersStatusBarHidden {
    return self.navigationController.isNavigationBarHidden;
}
Run Code Online (Sandbox Code Playgroud)

斯威夫特<= 2.3

override func prefersStatusBarHidden() -> Bool {
    return navigationController?.navigationBarHidden ?? false
}
Run Code Online (Sandbox Code Playgroud)

Swift 3.0

override var prefersStatusBarHidden: Bool {
    return navigationController?.isNavigationBarHidden ?? false
}
Run Code Online (Sandbox Code Playgroud)

并确保您的应用程序.plist文件中有"查看基于控制器的状态栏外观"="是".

  • 这应该被标记为最佳答案,简单而优雅. (2认同)

And*_*rew 30

建立anas的答案,我有一个有效的解决方案(我假设tableViewController是你的UITableViewController实例):

UINavigationController子类中(或也可能来自tableViewController):

- (void)viewDidLoad {
    if ([self respondsToSelector:@selector(barHideOnSwipeGestureRecognizer)]) {
        // iOS 8+
        self.hidesBarsOnSwipe = YES;
        [self.barHideOnSwipeGestureRecognizer addTarget:self action:@selector(swipe:)];
    }
}

- (void)swipe:(UISwipeGestureRecognizer *)recognizer {
    BOOL shouldHideStatusBar = self.navigationController.navigationBar.frame.origin.y < 0;
    tableViewController.hideStatusBar = shouldHideStatusBar;
    [UIView animateWithDuration:0.2 animations:^{
        [tableViewController setNeedsStatusBarAppearanceUpdate];
    }];
}
Run Code Online (Sandbox Code Playgroud)

在你的tableViewController:

@property(nonatomic, getter = shouldHideStatusBar) BOOL hideStatusBar;

- (BOOL)prefersStatusBarHidden {
    return [self shouldHideStatusBar];
}
Run Code Online (Sandbox Code Playgroud)

如果这对您不起作用,请告诉我.一些不明显的事情:

  • self.navigationController.navigationBar.frame.origin.y隐藏时为-44(导航栏的负高度),可见时为20(状态栏的高度).即使在动画期间也没有中间,所以负值==隐藏和非负值==可见.
  • 子视图控制器是查询是否应隐藏状态栏的控制器.在我的情况下,我有一个UIViewController在一个UINavigationController内部UITabBarController,它没有工作,直到我超越prefersStatusBarHiddenUIViewController.
  • 由于隐藏状态栏没有框架,因此除非将调用包装setNeedsStatusBarAppearanceUpdate在动画块中,否则您的内容可能会超过20分.
  • 希望语法是正确的; 我从我的Swift代码中反向移植了这个.


Ana*_*nas 8

这个新物业附带它barHideOnSwipeGestureRecognizer.

来自UINavigationController类参考:

您可以根据需要对手势识别器进行更改,但不得更改其委托,并且不得删除使用它配置的默认目标对象和操作.请勿尝试通过覆盖属性来替换此手势识别器.

但是你可以添加一个目标:

[self.navigationController setHidesBarsOnSwipe:YES];
[self.navigationController.barHideOnSwipeGestureRecognizer addTarget:self action:@selector(swipeGesture:)];
Run Code Online (Sandbox Code Playgroud)

...并在回调中做任何你想做的事情:

- (void)swipeGesture:(UIPanGestureRecognizer*)gesture
{
    // Tweak the status bar
}
Run Code Online (Sandbox Code Playgroud)

您可能必须手动打开手势状态,找出何时隐藏/显示状态栏等.希望有所帮助!