iOS9 扩展状态栏bug?
iOS 9 extended status bar bug?
我的应用程序出现问题,应用程序顶部有一个黑条,我的整个视图从顶部向下推 20pts。
这是一个非常简短的示例项目,它重现了该错误:https://github.com/sbiermanlytle/iOS-status-bar-bug/tree/master
重现:
- 激活扩展状态栏(在 Google 地图上开始路线或打开热点)
- 启动演示应用程序
- 导航到第三个视图
- 回到第二个视图,你会看到顶部的黑条
如何去掉黑条?
下面是示例应用的完整说明:
有一系列的 3 个视图控制器,1 个启动 2 个,UIViewControllerBasedStatusBarAppearance
设置为 YES
,第一个和第三个视图控制器隐藏状态栏,第二个显示状态栏。
当您启动第二个视图和第三个视图时,一切都显示正常,但是当您关闭第三个视图时,第二个视图顶部的黑条不会消失。
看起来像 iOS bug.
我不知道解决这个问题的绝妙方法,但这些肯定有效:
使用已弃用的 API
将 Info.plist 中的 View controller-based status bar appearance
条目更改为 NO
。将这样的代码添加到 all 你的视图控制器(或公共超类,希望你有一个;)):
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[UIApplication sharedApplication] setStatusBarHidden:[self prefersStatusBarHidden]];
}
使用丑陋的调整
通过在导致条件时手动更新失败系统视图的框架。这可能会或可能不会破坏测试应用程序之外的内容。
在UIViewController+TheTweak.h
#import <UIKit/UIKit.h>
@interface UIViewController (TheTweak)
- (void)transitionViewForceLayoutTweak;
@end
在 UIViewController+TheTweak.m
(注意 FIXME 评论)
#import "UIViewController+TheTweak.h"
#import "UIView+TheTweak.h"
@implementation UIViewController (TheTweak)
- (void)transitionViewForceLayoutTweak {
UIViewController *presenting = [self presentingViewController];
if (([self presentedViewController] != nil) && ([self presentingViewController] != nil)) {
if ([self prefersStatusBarHidden]) {
NSUInteger howDeepDownTheStack = 0;
do {
++howDeepDownTheStack;
presenting = [presenting presentingViewController];
} while (presenting != nil);
//FIXME: replace with a reliable way to get window throughout whole app, without assuming it is the 'key' one. depends on your app's specifics
UIWindow *window = [[UIApplication sharedApplication] keyWindow];
[window forceLayoutTransitionViewsToDepth:howDeepDownTheStack];
}
}
}
@end
在UIView+TheTweak.h
#import <UIKit/UIKit.h>
@interface UIView (TheTweak)
- (void)forceLayoutTransitionViewsToDepth:(NSUInteger)depth;
@end
在UIView+TheTweak.m
#import "UIView+TheTweak.h"
@implementation UIView (TheTweak)
- (void)forceLayoutTransitionViewsToDepth:(NSUInteger)depth {
if (depth > 0) { //just in case
for (UIView *childView in [self subviews]) {
if ([NSStringFromClass([childView class]) isEqualToString:@"UITransitionView"]) {
childView.frame = self.bounds;
if (depth > 1) {
[childView forceLayoutTransitionViewsToDepth:(depth - 1)];
}
}
}
}
}
@end
现在,在每个视图控制器(或公共超类)中:
#import "UIViewController+TheTweak.h"
... // whatever goes here
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self transitionViewForceLayoutTweak];
}
或者您可以将有问题的控制器的背景变成黑色 :)
最简单的调整
@interface SecondViewController ()
@property (assign, nonatomic) BOOL statusBarHidden;
@end
@implementation SecondViewController
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.statusBarHidden = [UIApplication sharedApplication].statusBarHidden; //store current state
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
self.statusBarHidden = YES;
[UIView animateWithDuration:0.2f animations:^{
[self setNeedsStatusBarAppearanceUpdate];
}];
}
- (BOOL)prefersStatusBarHidden {
return self.statusBarHidden;
}
@end
我的应用程序出现问题,应用程序顶部有一个黑条,我的整个视图从顶部向下推 20pts。
这是一个非常简短的示例项目,它重现了该错误:https://github.com/sbiermanlytle/iOS-status-bar-bug/tree/master
重现:
- 激活扩展状态栏(在 Google 地图上开始路线或打开热点)
- 启动演示应用程序
- 导航到第三个视图
- 回到第二个视图,你会看到顶部的黑条
如何去掉黑条?
下面是示例应用的完整说明:
有一系列的 3 个视图控制器,1 个启动 2 个,UIViewControllerBasedStatusBarAppearance
设置为 YES
,第一个和第三个视图控制器隐藏状态栏,第二个显示状态栏。
当您启动第二个视图和第三个视图时,一切都显示正常,但是当您关闭第三个视图时,第二个视图顶部的黑条不会消失。
看起来像 iOS bug.
我不知道解决这个问题的绝妙方法,但这些肯定有效:
使用已弃用的 API
将 Info.plist 中的 View controller-based status bar appearance
条目更改为 NO
。将这样的代码添加到 all 你的视图控制器(或公共超类,希望你有一个;)):
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[UIApplication sharedApplication] setStatusBarHidden:[self prefersStatusBarHidden]];
}
使用丑陋的调整
通过在导致条件时手动更新失败系统视图的框架。这可能会或可能不会破坏测试应用程序之外的内容。
在UIViewController+TheTweak.h
#import <UIKit/UIKit.h>
@interface UIViewController (TheTweak)
- (void)transitionViewForceLayoutTweak;
@end
在 UIViewController+TheTweak.m
(注意 FIXME 评论)
#import "UIViewController+TheTweak.h"
#import "UIView+TheTweak.h"
@implementation UIViewController (TheTweak)
- (void)transitionViewForceLayoutTweak {
UIViewController *presenting = [self presentingViewController];
if (([self presentedViewController] != nil) && ([self presentingViewController] != nil)) {
if ([self prefersStatusBarHidden]) {
NSUInteger howDeepDownTheStack = 0;
do {
++howDeepDownTheStack;
presenting = [presenting presentingViewController];
} while (presenting != nil);
//FIXME: replace with a reliable way to get window throughout whole app, without assuming it is the 'key' one. depends on your app's specifics
UIWindow *window = [[UIApplication sharedApplication] keyWindow];
[window forceLayoutTransitionViewsToDepth:howDeepDownTheStack];
}
}
}
@end
在UIView+TheTweak.h
#import <UIKit/UIKit.h>
@interface UIView (TheTweak)
- (void)forceLayoutTransitionViewsToDepth:(NSUInteger)depth;
@end
在UIView+TheTweak.m
#import "UIView+TheTweak.h"
@implementation UIView (TheTweak)
- (void)forceLayoutTransitionViewsToDepth:(NSUInteger)depth {
if (depth > 0) { //just in case
for (UIView *childView in [self subviews]) {
if ([NSStringFromClass([childView class]) isEqualToString:@"UITransitionView"]) {
childView.frame = self.bounds;
if (depth > 1) {
[childView forceLayoutTransitionViewsToDepth:(depth - 1)];
}
}
}
}
}
@end
现在,在每个视图控制器(或公共超类)中:
#import "UIViewController+TheTweak.h"
... // whatever goes here
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self transitionViewForceLayoutTweak];
}
或者您可以将有问题的控制器的背景变成黑色 :)
最简单的调整
@interface SecondViewController ()
@property (assign, nonatomic) BOOL statusBarHidden;
@end
@implementation SecondViewController
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.statusBarHidden = [UIApplication sharedApplication].statusBarHidden; //store current state
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
self.statusBarHidden = YES;
[UIView animateWithDuration:0.2f animations:^{
[self setNeedsStatusBarAppearanceUpdate];
}];
}
- (BOOL)prefersStatusBarHidden {
return self.statusBarHidden;
}
@end