objective-c 显示/隐藏具有流畅动画的导航栏
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2079590/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Showing/hiding navigation bar with smooth animation
提问by 4thSpace
I have a navigation based app. The first view (rootcontroller) starts with three large buttons only. No navigationbar. From there, everything else is tableviews and have navigation bars. I'm doing this to show/hide the navigation bar:
我有一个基于导航的应用程序。第一个视图(rootcontroller)仅以三个大按钮开始。没有导航栏。从那里,其他一切都是 tableviews 和导航栏。我这样做是为了显示/隐藏导航栏:
MyAppAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
appDelegate.navigationController.navigationBar.hidden = NO;
Once I leave the root controller, the navigation bar will jerk into place and lay on top of the tableview, rather than pushing it down. It clips the top part of the tableview. Going back to the root controller isn't smooth in how the navigation bar disappears. Is there a smoother/better way to do accomplish hiding the navigation bar for the root controller only?
一旦我离开根控制器,导航栏将猛地到位并位于 tableview 的顶部,而不是将其向下推。它剪辑 tableview 的顶部。导航栏消失的方式返回到根控制器并不顺利。是否有更流畅/更好的方法来完成仅隐藏根控制器的导航栏?
回答by James Raybould
回答by codeburn
This nifty bit of code animates the navigation bar hiding with no UI issues:
这段漂亮的代码使导航栏隐藏动画,没有 UI 问题:
[navigationController setNavigationBarHidden: YES animated:YES]
[navigationController setNavigationBarHidden: YES animated:YES]
But...
但...
- Use the self.navigationController.navigationBarHiddenproperty for checks in the code instead of the self.navigationController.navigationBar.hiddenproperty. This will save you a lot of pain from unexpected UI positioning problems.
- Take care to place this method in - (void)viewWillAppear:(BOOL)animatedor later in the view lifecycle. This is recommended because if you do it in - (void)viewDidLoadfor instance, you will get an ugly black rectangular view during animations from a view which displays its navigation bar to a view which doesn't! For example, if your home view has its navigation bar hidden but all its children have the navigation bar shown, when you pop to home view, the animation will show a black bar in place of the navigation bar until the animation completes
- 使用self.navigationController.navigationBarHidden属性来检查代码,而不是self.navigationController.navigationBar.hidden属性。这将为您免去意外 UI 定位问题带来的很多痛苦。
- 注意将此方法放在- (void)viewWillAppear:(BOOL)animated或视图生命周期的后面。这是推荐的,因为如果您在- (void)viewDidLoad 中执行此操作,您将在动画期间从显示其导航栏的视图到不显示导航栏的视图中获得丑陋的黑色矩形视图!例如,如果您的主页视图隐藏了导航栏,但其所有子视图都显示了导航栏,则当您弹出主页视图时,动画将显示一个黑色栏代替导航栏,直到动画完成
回答by Vignesh Kumar
You can customize the navigation bar animation and duration by the following methods. It will provide you callback once animation will be completed.
您可以通过以下方法自定义导航栏动画和持续时间。一旦动画完成,它将为您提供回调。
// 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");
}];


