iOS开发者肯定会知道有关状态栏和着名的“幻灯片/汉堡包/抽屉”的问题。这个问题在这里得到了很好的解释:http://uxmag.com/articles/adapting-ui-to-ios-7-the-side-menu
我正在使用MMDrawerController库,它有一个很好的黑客,让我们可以在容器视图控制器上方创建一个虚拟状态栏。不幸的是,这不是很好。有什么新的消息?新闻是我偶然发现了一个应用程序(Tinder),完美地解决了这个令人兴奋的问题。我创建了一个完美展示Tinder所做的GIF。
你需要等待几秒钟才能看到gif,因为它有一个错误而且我不知道如何摆脱它。只需等待一两秒钟就能正确看到gif。
无论如何,Tinder做什么?当用户点击左上方的菜单按钮并开始向右滑动时,状态栏整齐地淡出。当视图恢复到原始位置时,状态栏将再次显示。
我为此感到高兴和有点难过,因为这意味着必须才能做到这一点,但我真的不知道如何实现它(可能是黑客MMDrawerController
)。任何帮助都将非常感激。
重要
请注意方法setStatusBarHidden:
将完全隐藏状态栏,这意味着整个视图的高度为-20px。这显然不是解决方案,因为从gif可以看出视图没有被拉伸。
答案 0 :(得分:21)
您的主要问题是MMDrawerController
。如果你要深入了解它,你会发现许多与状态栏相关的方法,例如setShowsStatusBarBackgroundView
setStatusBarViewBackgroundColor
等等。当状态栏被隐藏时,代码中的某些内容会推动视图。
或者,您可以使用其他抽屉控制器或使用自定义代码。
以下是如何实现这一目标的简单方法:
ViewControllerA:
-(BOOL)prefersStatusBarHidden
{
return _hidden;
}
- (void)statusHide
{
[UIView animateWithDuration:0.4 animations:^() {[self setNeedsStatusBarAppearanceUpdate];
}completion:^(BOOL finished){}];
}
ViewControllerB :( ViewControllerA中的容器)
- (IBAction)move:(UIButton *)sender
{
parent = (ViewController*)self.parentViewController;
parent.hidden = !parent.hidden;
CGRect frame = parent.blueContainer.frame;
if(parent.hidden)
{
frame.origin.x = 150;
}
else
{
frame.origin.x = 0;
}
[UIView animateWithDuration:1 animations:^() {parent.blueContainer.frame = frame;}completion:^(BOOL finished){}];
[parent statusHide];
}
对于iOS 6 compatieblty使用:
[[UIApplication sharedApplication] setStatusBarHidden:_hidden withAnimation:UIStatusBarAnimationFade];
表格视图和其他子视图将保留在其位置,并且不会被推高。
修改强>
添加NavigationBar:
UINavigationController会将其UINavigationBar的高度更改为 无论是44分还是64分,取决于一个相当奇怪的和 未记录的约束集。如果UINavigationController检测到 它的视图框架的顶部在视觉上与其相邻 UIWindow的顶部,然后它绘制高度为64的导航栏 点。如果它的视图顶部与UIWindow的顶部不相邻 (即使只关闭一个点),然后它会绘制导航栏 高度为44分的“传统”方式。这个逻辑是 由UINavigationController执行,即使它是几个孩子 在应用程序的视图控制器层次结构内。那里 无法阻止这种行为。
取自here
您可以简单地将UINavigationController
子类化并创建自己的导航栏以避免这种烦恼。
答案 1 :(得分:5)
我不知道它是否能解决你的问题,但我使用SWRevealViewController项目得到了几乎相同的效果。在appDelegate中,我从这个类中设置了委托方法来执行此操作:
- (void)revealController:(SWRevealViewController *)revealController willMoveToPosition:(FrontViewPosition)position {
#ifdef DEBUG
NSArray *teste = @[@"FrontViewPositionLeftSideMostRemoved",@"FrontViewPositionLeftSideMost",@"FrontViewPositionLeftSide",@"FrontViewPositionLeft",@"FrontViewPositionRight",@"FrontViewPositionRightMost",@"FrontViewPositionRightMostRemoved"];
NSLog(@"%@ %d", teste[position], position);
#endif
if (position == FrontViewPositionRight)
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationFade];
UINavigationController *frontViewController = (id)revealController.frontViewController;
frontViewController.navigationBar.centerY += (position == FrontViewPositionRight) ? 20 : 0; // 20 == statusbar heihgt
}
- (void)revealController:(SWRevealViewController *)revealController didMoveToPosition:(FrontViewPosition)position {
if (position == FrontViewPositionLeft)
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationFade];
}
centerY是UIView中的一个类别,它设置center.y而不处理设置框架变量的无聊部分。
答案 2 :(得分:3)
以下是在iOS 7中应该如何做到这一点:
@implementation ViewController
{
BOOL _hideStatusBar;
}
-(UIStatusBarStyle)preferredStatusBarStyle
{
return UIStatusBarStyleDefault;
}
-(UIStatusBarAnimation)preferredStatusBarUpdateAnimation
{
return UIStatusBarAnimationFade;
}
-(BOOL)prefersStatusBarHidden
{
return _hideStatusBar;
}
-(void)setStatusBarHidden:(BOOL)hidden
{
[UIView animateWithDuration:1.0 animations:^{
_hideStatusBar = hidden;
[self setNeedsStatusBarAppearanceUpdate];
}];
}
@end
答案 3 :(得分:1)
查看setStatusBarHidden:withAnimation:
上的方法UIApplication
。它允许您显示或隐藏状态栏,动画可以是无,淡入淡出或幻灯片。你只需要添加一个隐藏栏的调用,然后在正确的时间显示一个栏,并确定你是否喜欢你所说明的淡入淡出或幻灯片是否适合你。
答案 4 :(得分:1)
如果您在-setStatusBarHidden:withAnimation:
中调整视图框,则可以使用-viewDidAppear:
,然后您将看不到任何拉伸。
请注意,自动布局已禁用。
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
CGRect frame = self.view.frame;
// adjust root view frame
frame.origin.y -= 20;
frame.size.height += 20;
[self.view setFrame:frame];
// adjust subviews y position
for (UIView *subview in [self.view subviews])
{
CGRect frame = subview.frame;
frame.origin.y += 20;
[subview setFrame:frame];
}
}
- (IBAction)sliderChanged:(id)sender
{
UISlider *s = (UISlider *)sender;
if (s.value > .5)
{
UIApplication *app = [UIApplication sharedApplication];
if (![app isStatusBarHidden])
[app setStatusBarHidden:YES withAnimation:UIStatusBarAnimationFade];
}
else
{
UIApplication *app = [UIApplication sharedApplication];
if ([app isStatusBarHidden])
[app setStatusBarHidden:NO withAnimation:UIStatusBarAnimationFade];
}
}