我有一个位于 UINavigationcontroller
内的 ViewController
,但导航栏是隐藏的。当我在 iOS 7 上运行应用程序时,状态栏显示在我的视图顶部。有没有办法避免这种情况?
我不想编写任何特定于操作系统的代码。
https://i.stack.imgur.com/IxX45.png
我尝试将 View controller-based status bar appearance
设置为 NO
,但没有解决问题。
Xcode 5 有 iOS 6/7 Deltas
专门用于解决此问题。在情节提要中,我将视图向下移动了 20 像素,以便在 iOS 7 上看起来正确,为了使其与 iOS 6 兼容,我将 Delta y
更改为 -20。
https://i.stack.imgur.com/e4P7J.png
由于我的故事板没有使用自动布局,为了在 iOS 6 上正确调整视图的高度,我必须设置 Delta height
和 Delta Y
。
如果您根本不想要任何状态栏,则需要使用以下数据更新您的 plist:为此,在 plist 中添加这 2 个设置:
<key>UIStatusBarHidden</key>
<true/>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
在 iOS 7 中,您应该在设计应用时考虑到覆盖透明状态栏。例如,请参阅新的 iOS 7 天气应用程序。
这是 iOS 7 上 UIViewController
的默认行为。视图将是全屏的,这意味着状态栏将覆盖视图的顶部。
如果您在 UINavigationController
中有一个 UIViewController
并且导航栏是可见的,那么您可以在 viewDidLoad
中包含以下代码或为导航栏添加背景图片来解决问题。
self.edgesForExtendedLayout = UIRectEdgeNone;
如果您隐藏了导航栏,那么您必须通过移动 20 个点来调整所有 UIView 元素。我没有看到任何其他解决方案。使用自动布局会有所帮助。
如果您想向后兼容,这里是用于检测 iOS 版本的示例代码。
NSUInteger DeviceSystemMajorVersion() {
static NSUInteger _deviceSystemMajorVersion = -1;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSString *systemVersion = [UIDevice currentDevice].systemVersion;
_deviceSystemMajorVersion = [[systemVersion componentsSeparatedByString:@"."][0] intValue];
});
return _deviceSystemMajorVersion;
}
if ([self respondsToSelector:@selector(edgesForExtendedLayout)])
而不是获取、解析和比较系统版本
我自己制作的唯一可行的解决方案。
这是我的 UIViewController 子类 https://github.com/comonitos/ios7_overlaping
1 UIViewController 的子类
从该类子类化您的 window.rootViewController。
3 瞧!
- (void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
CGRect screen = [[UIScreen mainScreen] bounds];
if (self.navigationController) {
CGRect frame = self.navigationController.view.frame;
frame.origin.y = 20;
frame.size.height = screen.size.height - 20;
self.navigationController.view.frame = frame;
} else {
if ([self respondsToSelector: @selector(containerView)]) {
UIView *containerView = (UIView *)[self performSelector: @selector(containerView)];
CGRect frame = containerView.frame;
frame.origin.y = 20;
frame.size.height = screen.size.height - 20;
containerView.frame = frame;
} else {
CGRect frame = self.view.frame;
frame.origin.y = 20;
frame.size.height = screen.size.height - 20;
self.view.frame = frame;
}
}
}
}
添加这个让你的状态栏变白就在[self.window makeKeyAndVisible]之后; !!!
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
}
-(UIStatusBarStyle)preferredStatusBarStyle
{
return UIStatusBarStyleLightContent;
}
-(void)viewWillLayoutSubviews{
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7)
{
self.view.clipsToBounds = YES;
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat screenHeight = 0.0;
if(UIDeviceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation]))
screenHeight = screenRect.size.height;
else
screenHeight = screenRect.size.width;
CGRect screenFrame = CGRectMake(0, 20, self.view.frame.size.width,screenHeight-20);
CGRect viewFrame1 = [self.view convertRect:self.view.frame toView:nil];
if (!CGRectEqualToRect(screenFrame, viewFrame1))
{
self.view.frame = screenFrame;
self.view.bounds = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
}
}
}
在 plist 中添加键---查看基于控制器的状态栏外观:否
要在 ios7 中隐藏状态栏,请执行以下简单步骤:
在 Xcode 中转到“Resources
”文件夹并打开“(app name)-Info.plist file
”。
检查“基于视图控制器的状态栏外观”键并将其值设置为“否”
检查“状态栏最初隐藏”键并将其值设置为“是”
如果键不存在,那么您可以通过选择顶部的“information property list
”并单击 + 图标来添加它
如果你想完全隐藏它并避免处理它,这很好用。
-(BOOL) prefersStatusBarHidden
{
return YES;
}
参考https://stackoverflow.com/a/18873777/1030449
如果使用 xib
,一个非常简单的实现是将所有子视图封装在一个容器视图中,并带有调整大小标志(您已经使用它来实现 3.5" 和 4" 的兼容性),以便视图层次结构看起来像这样
https://i.stack.imgur.com/iJkfp.png
然后在 viewDidLoad
中,执行以下操作:
- (void)viewDidLoad
{
[super viewDidLoad];
// initializations
if(SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) // only for iOS 7 and above
{
CGRect frame = containerView.frame;
frame.origin.y += 20;
frame.size.height -= 20;
containerView.frame = frame;
}
}
这样,无需针对 iOS 7 兼容性修改笔尖。如果你有背景,可以把它放在containerView
之外,让它覆盖整个屏幕。
https://i.stack.imgur.com/RsCCW.png
对于导航栏:
编写此代码:
self.navigationController.navigationBar.translucent = NO;
只是为我做了伎俩。
文森特的回答 edgeForExtendedLayout 对我有用。
这些宏有助于确定操作系统版本,使其更容易
// 7.0 and above
#define IS_DEVICE_RUNNING_IOS_7_AND_ABOVE() ([[[UIDevice currentDevice] systemVersion] compare:@"7.0" options:NSNumericSearch] != NSOrderedAscending)
// 6.0, 6.0.x, 6.1, 6.1.x
#define IS_DEVICE_RUNNING_IOS_6_OR_BELOW() ([[[UIDevice currentDevice] systemVersion] compare:@"6.2" options:NSNumericSearch] != NSOrderedDescending)
将这些宏添加到项目的 prefix.pch 文件中,并且可以在任何地方访问
if(IS_DEVICE_RUNNING_IOS_7_AND_ABOVE())
{
//some iOS 7 stuff
self.edgesForExtendedLayout = UIRectEdgeNone;
}
if(IS_DEVICE_RUNNING_IOS_6_OR_BELOW())
{
// some old iOS stuff
}
我已经将我的答案发布到另一篇与这个问题相同的帖子中。
来自 Apple iOS7 过渡指南,https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/TransitionGuide/AppearanceCustomization.html#//apple_ref/doc/uid/TP40013174-CH15-SW1
当我不想重叠并且我有 tableviewcontroller
时,特别是 automaticallyAdjustsScrollViewInsets=YES
和 set self.edgesForExtendedLayout = UIRectEdgeNone
对我有用。
如果您希望不惜一切代价启用“使用自动布局”,请将以下代码放在 viewdidload.xml 中。
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7)
{
self.edgesForExtendedLayout = UIRectEdgeNone;
self.extendedLayoutIncludesOpaqueBars = NO;
self.automaticallyAdjustsScrollViewInsets = NO;
}
从 YTPlayer 的横向视图返回后,我的状态栏和导航栏重叠。这是我尝试@comonitos 的版本后的解决方案,但不适用于我的 iOS 8
- (void)fixNavigationBarPosition {
if (self.navigationController) {
CGRect frame = self.navigationController.navigationBar.frame;
if (frame.origin.y != 20.f) {
frame.origin.y = 20.f;
self.navigationController.navigationBar.frame = frame;
}
}
}
只要你想固定导航栏的位置,就调用这个函数。我调用了 YTPlayerViewDelegate 的 playerView:didChangeToState:
- (void)playerView:(YTPlayerView *)playerView didChangeToState:(YTPlayerState)state {
switch (state) {
case kYTPlayerStatePaused:
case kYTPlayerStateEnded:
[self fixNavigationBarPosition];
break;
default:
}
}