How to prevent status bar from overlapping content with hidesBarsOnSwipe set on UINavigationController?

后端 未结 9 890
灰色年华
灰色年华 2020-12-02 11:10

I\'m trying to use the new feature added in iOS 8 - hiding the navigation bar while user is scrolling the table view (similar to what mobile Safari does). I\'m setting the p

9条回答
  •  不思量自难忘°
    2020-12-02 12:11

    Building off of anas' answer, I have a working solution (I'm assuming tableViewController is your UITableViewController instance):

    In a UINavigationController subclass (or also potentially from 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];
        }];
    }
    

    In your tableViewController:

    @property(nonatomic, getter = shouldHideStatusBar) BOOL hideStatusBar;
    
    - (BOOL)prefersStatusBarHidden {
        return [self shouldHideStatusBar];
    }
    

    Let me know if this doesn't work for you. A few non-obvious things:

    • self.navigationController.navigationBar.frame.origin.y was -44 (the negative height of the navigation bar) when hidden, and 20 (the height of the status bar) when visible. There was no in-between, even during animations, so a negative value == hidden and a nonnegative value == visible.
    • The child view controller is the one queried for whether or not the status bar should be hidden. In my case, I have a UIViewController within a UINavigationController within a UITabBarController, and it didn't work until I overrode prefersStatusBarHidden on the UIViewController.
    • Since a hidden status bar has no frame, your content might jerk upwards 20 points unless you wrap the call to setNeedsStatusBarAppearanceUpdate in an animation block.
    • Hopefully the syntax is correct; I backported this from my Swift code.

提交回复
热议问题