iOS 7状态栏与NavigationBar碰撞
我在我的应用程序中有一个视图控制器,在故事板上有一个导航栏拖动它。 它在iOS 6中工作正常,但在iOS 7中它看起来像这样:
状态栏和导航栏不应该相互碰撞。 我在堆栈溢出中看到了很多这样的问题,但对我来说帮助不大。
有些问题说我应该使用这个“self.edgesForExtendedLayout = UIRectEdgeNone;” 但它没有工作。 有人说我应该删除导航栏,并将其embedded导航控制器,我不能做,因为我的程序的实施方式。 一些解决schemebuild议使用视图边界和所有,但它不适合我。
什么是可以帮助我解决这个问题的一件事。 提前致谢!
更新:我已经embedded视图控制器内的uinavigation控制器。 删除了之前手动添加的导航栏。 现在看起来好像在故事板,但是当我运行它,它显示以下内容:
它显示来自另一个视图控制器的文本,该视图控制器当前位于其父视图控制器之后。 意味着它现在透明。 任何人都可以指出我做错了什么?
iOS的最新版本带来了许多视觉上的变化,从开发者的angular度来看,导航和状态栏是两个明显的变化。
状态栏现在是透明的,并在其后面的导航栏显示。 导航栏图像甚至可以在状态栏后面扩展。
首先,如果你是一个初学者,刚刚开始iOS开发,并且对状态栏和导航栏的工作方式感到困惑,那么你可以简单地通过一个博客文章, 这里我发现非常有用。 它具有与iOS 7中的导航和状态栏有关的所有信息。
现在来回答你的问题。 首先我可以看到两个不同的问题。 一个是你的状态栏和导航栏都是相互碰撞,如你在图像的问题中所示。
问题:问题在于你的视图控制器已经在iOS 6中正确工作了,但是随着iOS 7 SDK的到来,这种方法导致状态栏和导航栏相互重叠。
第一个问题的解决scheme:您可以使用UIBarPositionTopAttached,也可以使用视图边界和框架,我也可以build议并链接到Apple的文档和Bla bla bla,但这需要一些时间来解决问题。
解决这个问题的最好也是最简单的方法就是将你的视图控制器embedded到导航控制器中。 你可以通过select视图控制器并转到编辑器>embedded>导航控制器来完成 。 (如果您的旧导航栏上有任何内容,您可以先将其拖动,将视图控制器embedded到导航控制器中,然后移动新导航栏上的栏button,然后删除旧的导航栏)
对第二个问题的解决scheme:这个解决scheme是针对你在更新中提到的具体问题,而不是让公众阅读。 正如你所看到的,导航和状态栏不可见,透明区域显示父视图控制器。 我不是真正使用你为什么面临这个问题,但最有可能的,因为像ECSlidingView或任何其他第三方库涉及。 您可以在故事板中select此视图控制器,并将视图的背景色设置为与您的导航栏相同。 这将停止在后面显示父视图控制器,您的导航栏和状态栏将开始显示。 现在你可以用文本视图或者你正在使用的视图控制器来覆盖其他的视图控制器。
希望这可以帮助!
导航栏离状态栏太近,因为从iOS 7开始,状态栏更多的是覆盖整个视图控制器的视图。 由于导航栏位于(0,0),因此状态栏将显示在导航栏的顶部。 为了解决这个问题,只需简单地移动导航栏(或者像其他人所说的那样),在导航栏和topLayoutGuide之间创build一个约束。
当你这样做的时候,你会看到导航栏和屏幕上方之间有20点的距离。 那是因为你刚刚把导航栏下移了20点。 “但是UINavigationController
可以做到这一点!” 绝对,它通过在您的视图控制器上实现UIBarPositioningDelegate
。 这是一个单方法的协议,应该像这样实现:
- (UIBarPosition)positionForBar:(id<UIBarPositioning>)bar { return UIBarPositionTopAttached; }
将视图控制器添加为导航栏的代表后,您会注意到导航栏仍然向下移动20个点,但是其背景将在状态栏下方延伸,就像在UINavigationController
。
另一件你看到的是导航栏是半透明的,这意味着在导航栏下面的任何东西都会在一定程度上可见。 UINavigationBar
上的translucent
属性在iOS 7上默认设置为YES
。在iOS 7之前,默认为NO
。
你可以简单地做到这一点:
1)在导航栏和顶部布局指南之间添加约束(select导航栏 ,按住Ctrl键并转到底部布局指南,取消按住Ctrl键)
2)select垂直间距 :
3)将常数设置为0 :
结果:
UPDATE
在你的AppDelegate文件中,你可以添加这个:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { // Prevent Navigationbar to cover the view UINavigationBar.appearance().translucent = false }
我build议你在你的viewDidLoad方法中尝试:
self.navigationController.navigationBar.translucent = NO;
(默认情况下,现在是)
这对我的作品,我希望你也有同样的运气:)。
在您的视图中添加以下代码。
-(void) viewDidLayoutSubviews { CGRect tmpFram = self.navigationController.navigationBar.frame; tmpFram.origin.y += 20; self.navigationController.navigationBar.frame = tmpFram; }
它基本上改变了导航栏的位置。
这是IOS7的新function。 而不是盯着0px的IOS7 20导航条。 作为解决scheme将整个视图向下移动到20像素,或者您可以使用图像导航栏高度为64px。
如果它仍然可以帮助某人,这是我在ios 7及以上版本中移动导航栏一点点的工作:
-(void)viewWillLayoutSubviews { float iosVersion = 7.0; if ([[[UIDevice currentDevice] systemVersion] floatValue] >= iosVersion) { // iOS 7+ CGRect viewFrame = self.view.frame; viewFrame.origin.y += 10; self.view.frame = viewFrame; } }
在ios 6.1及以下版本的导航栏上的设备将保持不变,就像以前一样。
这是我用来使状态栏的内容更轻:
-(UIStatusBarStyle)preferredStatusBarStyle{ return UIStatusBarStyleLightContent; }
如果您的UIViewController
不在UINavigationController
并且您正在使用UIStoryBoard
,那么您可以将每个子视图的UIStatusBar
每个子视图都设置为“Y 6/7 Deltas”为20。
首先,在Info.plist中将UIViewControllerBasedStatusBarAppearance
设置为NO。 然后,在AppDelegate
的application:didFinishLaunchingWithOptions:
方法add:
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) { [application setStatusBarStyle:UIStatusBarStyleLightContent]; self.window.clipsToBounds = YES; self.window.frame = CGRectMake(0, 20, self.window.frame.size.width, self.window.frame.size.height-20); self.window.bounds = CGRectMake(0, 20, self.window.frame.size.width, self.window.frame.size.height); } return YES;
在iOS 7应用程序占用屏幕大小的100%。这不是一个问题。 http://www.doubleencore.com/2013/09/developers-guide-to-the-ios-7-status-bar/
在早期的iOS窗口启动后,状态栏和iOS 7窗口从早期版本的0px开始视图高度是460(iPhone 4s和更早版本)和548(iPhone 5),但在iOS 7视图高度是480(iPhone 4s和更早版本)和568 (iPhone 5及更高版本),所以您必须在2o px之后开始视图排列,或者您必须从20px开始查看。
你可以在下面的代码写在rootviewcontroller或在所有viewcontroller从20px设置视图
#define IOS7_HEIGHT 64 - (void)viewDidLayoutSubviews { NSString *currSysVer = [[UIDevice currentDevice] systemVersion]; if ([currSysVer compare:@"7.0" options:NSNumericSearch] != NSOrderedAscending) { CGRect frame=[self.view frame]; if (frame.origin.y!=IOS7_HEIGHT) { frame.origin.y = IOS7_HEIGHT; frame.size.height -= IOS7_HEIGHT; [self.view setFrame:frame]; [self.view layoutSubviews]; } } }
这里的高度是64,因为20是状态栏,44是导航栏。 尝试下面的代码,它会帮助你。 你的问题就解决了
对于执行@Masterfego解决scheme(也是官方的,但是我在Xcode 6.3和自动约束方面遇到问题)的人来说,这就是我所做的:
我有一个UIViewController与添加导航栏。 我selectNAvigation栏并添加了64px的高度限制。 我们后来看到一个警告,导航栏会更高(但这是我们所做的)。 最后,你可以看到状态栏看起来不错,并且与导航栏颜色相同。 🙂
PS:我现在还不能发布图片。
使用Swift :
正如@Scott Berrevoets在他的回答中所说的,你需要在协议UIBarPositioningDelegate
实现方法positionForBar
,但是由于UINavigationBarDelegate
协议实现了这个协议:
public protocol UINavigationBarDelegate : UIBarPositioningDelegate { ... }
您只需要设置使用Storyboard设置的UINavigationBar
的delegate
并实现该方法,并完成,就像这样:
class ViewController: UIViewController, UINavigationBarDelegate { @IBOutlet weak var navigationBar: UINavigationBar! override func viewDidLoad() { super.viewDidLoad() self.navigationBar.delegate = self } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } func positionForBar(bar: UIBarPositioning) -> UIBarPosition { return UIBarPosition.TopAttached } }
注意:值得一提的是,如果你设置导航栏的y轴的位置,让我们假设从顶部到40,然后从这个位置UINavigationController
延伸到顶部,以模拟你需要的UINavigationController
的行为从顶端设置为20。
我希望这会帮助你。
您可以创build附加到顶部布局指南的约束来指定导航栏相对于状态栏的位置。 有关使用布局指南的更多信息,请参阅iOS 7 UI过渡指南:外观和行为部分 。
这是最好的答案。 但我想知道如何使用Storyboard
并拖动它的UINavigationBar
。 当我实现委托方法,并将返回结果设置为UIBarPositionTopAttached
,它不起作用。
- (void)viewDidLoad{ self.navigationbar.delegate = self; } - (UIBarPosition)positionForBar:(id<UIBarPositioning>)bar{ NSLog(@"Got it"); // // CGRect frame = self.navigaitonBar.frame; // // frame = CGRectMake(0, 20, CGRectGetWidth(frame), CGRectGetHeight(frame)); // self.navigaitonBar.frame = frame; // // NSLog(@"frame %f",frame.origin.y); return UIBarPositionTopAttached; }
如果你使用Xcode 6和Swift,你可以这样做:
- 打开您的应用程序的info.plist文件。
- 如果不存在,则添加一个ViewControllerBasedStatusBarAppearance布尔键,并赋值“NO”。
- 如果不存在,添加“状态栏风格”键,并select“不透明黑色风格”值。