首页 文章

显示/隐藏带有平滑动画的导航栏

提问于
浏览
50

我有一个基于导航的应用程序 . 第一个视图(rootcontroller)仅以三个大按钮开头 . 没有导航栏 . 从那里,其他一切都是tableviews和导航栏 . 我这样做是为了显示/隐藏导航栏:

MyAppAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
appDelegate.navigationController.navigationBar.hidden = NO;

一旦我离开根控制器,导航栏就会猛拉到位并放在桌面视图的顶部,而不是将其向下推 . 它剪辑了tableview的顶部 . 回到根控制器并不是导航栏消失的方式 . 是否有更顺畅/更好的方法来完成隐藏根控制器的导航栏?

3 回答

  • 115

    您可以使用 [navigationController setNavigationBarHidden:YES animated:YES] 平滑地隐藏栏 .

    Reference

  • 9

    这段漂亮的代码动画隐藏了导航栏,没有UI问题:

    但......

    • 使用 self.navigationController.navigationBarHidden 属性检查代码而不是 self.navigationController.navigationBar.hidden 属性 . 这将为您带来意外的UI定位问题带来的痛苦 .

    • 注意将此方法放在视图生命周期的 - (void)viewWillAppear:(BOOL)animated 或更高版本中 . 这是推荐的,因为如果你在 - (void)viewDidLoad 中这样做,你会在视图中获得一个丑陋的黑色矩形视图,从视图中显示其导航栏到一个不显示的视图!例如,如果您的主视图隐藏了其导航栏但其所有子项都显示了导航栏,则当您弹出到主视图时,动画将显示黑色条代替导航栏,直到动画完成

  • 2

    您可以通过以下方法自定义导航栏动画和持续时间 . 一旦动画完成,它将为您提供回调 .

    // pass a param to describe the state change, an animated flag and a completion block matching UIView animations completion
        - (void)setNavigationBarVisible:(BOOL)visible animated:(BOOL)animated completion:(void (^)(BOOL))completion {
    
            // fail if the current state matches the desired state
            if ([self navigationBarIsVisible] == visible) return completion(YES);
    
            // get a frame calculation ready
            CGFloat nheight = self.navigationController.navigationBar.frame.size.height;
            CGFloat noffsetY = (visible)? -nheight : nheight;
    
            // zero duration means no animation
            CGFloat duration = (animated)? 0.3 : 0.0;
    
            [UIView animateWithDuration:duration animations:^{
                CGRect nframe = self.navigationController.navigationBar.frame;
                self.navigationController.navigationBar.frame = CGRectOffset(nframe, 0, noffsetY);
            } completion:completion];
        }
    
        // know the current state of the navigation bar
        - (BOOL)navigationBarIsVisible {
            return self.navigationController.navigationBar.frame.origin.y < CGRectGetMinY(self.view.frame);
        }
    
        // Show or Hide navigation bar
        [self setNavigationBarVisible:![self navigationBarIsVisible] animated:YES completion:^(BOOL finished) {
            NSLog(@"navigation bar finished");
        }];
    

    隐藏导航栏之前:

    Before hide a Navigation bar:

    隐藏导航栏后:

    After hide a Navigation bar:

相关问题