我想点击状态栏的可见性,就像在照片应用中一样。
在iOS 7之前,此代码运行良好:
-(void)setStatusBarIsHidden:(BOOL)statusBarIsHidden {
_statusBarIsHidden = statusBarIsHidden;
if (statusBarIsHidden == YES) {
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationFade];
}else{
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationFade];
}
}
但是我无法在iOS 7中使用它。我发现的所有答案都只提供永久隐藏栏但不切换的建议。
然而,必须有一种方式,因为照片做到了。
答案 0 :(得分:44)
默认情况下,在iOS 7或更高版本上,要隐藏特定视图控制器的状态栏,请执行以下操作:
modalPresentationStyle
不是UIModalPresentationFullScreen
,请在呈现时手动将modalPresentationCapturesStatusBarAppearance
设置为YES
控制器在呈现之前(例如,如果您使用的是故事板,则在-presentViewController:animated:completion
或-prepareForSegue:
中)-prefersStatusBarHidden
并返回适当的值setNeedsStatusBarAppearanceUpdate
如果要为其外观或消失设置动画,请在动画块中执行第三步:
[UIView animateWithDuration:0.33 animations:^{
[self setNeedsStatusBarAppearanceUpdate];
}];
您还可以通过在显示的控制器中从UIStatusBarAnimation
返回适当的-preferredStatusBarUpdateAnimation
值来设置动画样式。
答案 1 :(得分:6)
首先将Info.plist中的View controller-based status bar appearance
设置为YES
此Swift示例显示了在按下按钮后如何使用动画切换StatusBar。
import UIKit
class ToggleStatusBarViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func prefersStatusBarHidden() -> Bool {
return !UIApplication.sharedApplication().statusBarHidden
}
override func preferredStatusBarUpdateAnimation() -> UIStatusBarAnimation {
return UIStatusBarAnimation.Slide
}
@IBAction func toggleStatusBar(sender: UIButton) {
UIView.animateWithDuration(0.5,
animations: {
self.setNeedsStatusBarAppearanceUpdate()
})
}
}
答案 2 :(得分:5)
我能够简化@ Jon的答案,并且仍然可以与iOS 7上的照片应用程序区分开来。看起来像展示时的延迟更新是不必要的。
- (IBAction)toggleUI:(id)sender {
self.hidesUI = !self.hidesUI;
CGRect barFrame = self.navigationController.navigationBar.frame;
CGFloat alpha = (self.hidesUI) ? 0.0 : 1.0;
[UIView animateWithDuration:0.33 animations:^{
[self setNeedsStatusBarAppearanceUpdate];
self.navigationController.navigationBar.alpha = alpha;
}];
self.navigationController.navigationBar.frame = CGRectZero;
self.navigationController.navigationBar.frame = barFrame;
}
- (BOOL)prefersStatusBarHidden {
return self.hidesUI;
}
答案 3 :(得分:4)
这可能被认为是一个黑客,但它是我最接近再现效果。还有一个小问题。淡出时,您可以看到导航栏从顶部调整大小。这是微妙的,但仍然不是一个完美的褪色。如果有人知道如何解决它,请告诉我!
- (BOOL)prefersStatusBarHidden {
if (_controlsAreHidden == YES)
return YES;
else
return NO;
}
- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation {
return UIStatusBarAnimationFade;
}
-(void)setControlsAreHidden:(BOOL)controlsAreHidden {
_controlsAreHidden = controlsAreHidden;
if (controlsAreHidden == YES) {
// fade out
//
CGRect barFrame = self.navigationController.navigationBar.frame;
[UIView animateWithDuration:0.3 animations:^ {
[self setNeedsStatusBarAppearanceUpdate];
self.navigationController.navigationBar.alpha = 0;
}];
self.navigationController.navigationBar.frame = CGRectMake(0, 20, barFrame.size.width, 44);
}else{
// fade in
//
CGRect barFrame = self.navigationController.navigationBar.frame;
self.navigationController.navigationBar.frame = CGRectMake(0, 20, barFrame.size.width, 64);
[UIView animateWithDuration:0.3 animations:^ {
[self setNeedsStatusBarAppearanceUpdate];
self.navigationController.navigationBar.alpha = 1;
}];
}
}
答案 4 :(得分:3)
此代码完美无缺:
-(void)setControlsAreHidden:(BOOL)controlsAreHidden {
if (_controlsAreHidden == controlsAreHidden)
return;
_controlsAreHidden = controlsAreHidden;
UINavigationBar * navigationBar = self.navigationController.navigationBar;
if (controlsAreHidden == YES) {
// fade out
//
CGRect barFrame = self.navigationController.navigationBar.frame;
[UIView animateWithDuration:0.3 animations:^ {
[self setNeedsStatusBarAppearanceUpdate];
self.navigationController.navigationBar.alpha = 0;
}];
self.navigationController.navigationBar.frame = CGRectZero;
self.navigationController.navigationBar.frame = CGRectMake(0, 20, barFrame.size.width, 44);
} else {
// fade in
//
[UIView animateWithDuration:UINavigationControllerHideShowBarDuration animations:^ {
[self setNeedsStatusBarAppearanceUpdate];
}];
double delayInSeconds = 0.01;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[self.navigationController setNavigationBarHidden:NO animated:NO];
navigationBar.alpha = 0;
[UIView animateWithDuration:UINavigationControllerHideShowBarDuration animations:^ {
navigationBar.alpha = 1;
}];
});
}
}
答案 5 :(得分:3)
实际上现在需要弄乱导航条框架。只需使用2个独立的动画块即可实现平滑动画。像这样的东西应该可以正常工作。
@property (nonatomic, assign) BOOL controlsShouldBeHidden;
...
- (void)setControlsHidden:(BOOL)hidden animated:(BOOL)animated {
if (self.controlsShouldBeHidden == hidden) {
return;
}
self.controlsShouldBeHidden = hidden;
NSTimeInterval duration = animated ? 0.3 : 0.0;
[UIView animateWithDuration:duration animations:^(void) {
[self setNeedsStatusBarAppearanceUpdate];
}];
[UIView animateWithDuration:duration animations:^(void) {
CGFloat alpha = hidden ? 0 : 1;
[self.navigationController.navigationBar setAlpha:alpha];
}];
}
- (BOOL)prefersStatusBarHidden {
return self.controlsShouldBeHidden;
}
为了与iOS 6兼容,请务必检查[self respondsToSelector:@selector(setNeedsStatusBarAppearanceUpdate)]
答案 6 :(得分:1)
解决此问题的方法取决于应用程序plist中“基于视图控制器的状态栏外观”设置的值。
如果您的plist中的“查看基于控制器的状态栏外观”为NO
,则此代码应该有效:
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationFade];
如果启用了“查看基于控制器的状态栏外观”,则在视图控制器中添加以下方法:
- (BOOL) prefersStatusBarHidden {
// I've hardcoded to YES here, but you can return a dynamic value to meet your needs for toggling
return YES;
}
对于切换,当您想要根据上述方法的值更改是否隐藏/显示状态栏时,视图控制器可以调用setNeedsStatusBarAppearanceUpdate
方法。
答案 7 :(得分:1)
要解决此问题,导航栏在淡入淡出时向上滑动,您应添加以下代码:
self.navigationController.navigationBar.frame = CGRectZero;
进入以下代码行之前的“淡入”部分:
self.navigationController.navigationBar.frame = CGRectMake(0, 20, barFrame.size.width, 64);
这是必要的,因为框架是相同的,设置相同的框架将被忽略,并且不会阻止导航栏滑动。因此,您需要将帧更改为不同的帧,然后再将其设置为正确的帧以触发更改。