Search code examples
iosobjective-cuitableviewuinavigationcontrolleruitabbarcontroller

UITableView: Shrink Tab Bar and Navigation Bar on Swipe up


Scenario

I have an app that uses a Tab Bar Controller (bottom of the screen) with a Navigation Controller (top of the screen) UI design. On one view controller I have a UITableView with content that the user will "Swipe Up" for to scroll through the table to view the content.

Need

Much like the Yahoo! and Instagram app, I'd like to be able to have the top Nav Bar and the bottom Tab Bar "shrink" and "disappear" when it senses the user is swiping up on the tableView. And of course, when the user swipes down again, I'd like them both to reappear.

Question

Does anyone know how to do this?


Solution

  • To hide UITabbar of UITabbarController which contains UINavigationController with UITableViewController in stack one should use hidesBarsOnSwipe property and add custom selector for barHideOnSwipeGestureRecognizer:

    @implementation SomeTableViewController
    
    - (void)willMoveToParentViewController:(UIViewController *)parent
    {
        if (parent) {
            self.navigationController.hidesBarsOnSwipe = YES;
            [self.navigationController.barHideOnSwipeGestureRecognizer addTarget:self action:@selector(swipe:)];
        }
        else {
            self.navigationController.hidesBarsOnSwipe = NO;
            [self.navigationController.barHideOnSwipeGestureRecognizer removeTarget:self action:@selector(swipe:)];
        }
    }
    
    - (void)swipe:(UIPanGestureRecognizer *)recognizer
    {
        UINavigationBar *bar = self.navigationController.navigationBar;
    
        BOOL isHidden = (bar.frame.origin.y < 0);
    
        [self.tabBarController.tabBar setHidden:isHidden];
    
        [[UIApplication sharedApplication] setStatusBarHidden:isHidden withAnimation:UIStatusBarAnimationSlide];
    }
    

    In this way one can hide both tabbar and statusBar. Also one can add some animation effects for hiding/revealing these bars.

    It is very important to remove selector before self has been deallocated. Otherwise, you will get guaranteed crash on the next use of barHideOnSwipeGestureRecognizer with self.navigationController.

    Note this approach is admissible only for iOS8+.