47

我的应用程序中有一个视图控制器,它在情节提要中拖了一个导航栏。它在 iOS 6 中运行良好,但在 iOS 7 中看起来像这样:

ios 7 状态栏导航 var

状态栏和导航栏不应相互碰撞。我在堆栈溢出上看到了很多这样的问题,但它们对我没有多大帮助。

有些问题说我应该使用这个“self.edgesForExtendedLayout = UIRectEdgeNone;” 但它没有用。有人说我应该删除导航栏并将其嵌入导航控制器中,由于我的程序实现方式,我无法做到这一点。一些解决方案建议使用视图边界,但它对我也不起作用。

可以帮助我解决此问题的一件事是什么。提前致谢!

更新:我已将视图控制器嵌入到 uinavigation 控制器中。删除了之前手动添加的导航栏。现在它在情节提要中看起来不错,但是当我运行它时,它显示以下内容:

iOS 7 导航状态栏

它显示来自当前位于其后面的另一个视图控制器的文本,即其父视图控制器。意味着它现在是透明的。谁能指出我做错了什么?

4

17 回答 17

65

最新版本的 iOS 带来了许多视觉上的变化,从开发者的角度来看,导航和状态栏是两个明显的变化。

状态栏现在是透明的,它后面的导航栏显示出来。导航栏图像甚至可以延伸到状态栏后面。

首先,如果您是初学者并且刚刚开始 iOS 开发并且对状态栏和导航栏的工作方式感到困惑,您可以简单地阅读我发现非常有用的博客文章HERE 。它拥有 iOS 7 中与导航和状态栏相关的所有信息。

现在来回答你的问题。首先,我可以看到两个不同的问题。一个是您的状态栏和导航栏都相互碰撞,如您在带有图像的问题中所示。

问题:问题是您之前在视图控制器中拖动了一个导航栏,该导航栏在 iOS 6 中正常工作,但随着 iOS 7 SDK 的到来,这种方法导致状态栏和导航栏相互重叠。

第一个问题的解决方案:您可以使用 UIBarPositionTopAttached 或者您可以使用视图边界和框架,我也可以建议并将您链接到Apple 的文档和 bla bla bla ,但这需要一些时间来解决问题。

解决此问题的最佳和最简单的方法是将视图控制器嵌入导航控制器中,仅此而已。您只需选择视图控制器并转到 Editor > Embed In > Navigation Controller 即可。(如果你的旧导航栏有内容,可以先往下拉,将视图控制器嵌入到导航控制器中,然后移动新导航栏上的栏按钮,然后删除旧导航栏)

第二个问题的解决方案:此解决方案适用于您在更新中提到的特定问题,不适用于阅读本文的公众。如您所见,导航和状态栏不可见,透明区域显示父视图控制器。我并没有真正使用您为什么面临这个问题,但很可能是因为涉及到一些第三方库,如 ECSlidingView 或任何其他库。您可以在情节提要中选择此视图控制器,并将视图的背景颜色设置为与导航栏相同。这将停止在后面显示父视图控制器,并且您的导航栏和状态栏将开始显示。现在您可以使用文本视图或您在其中使用的任何内容来覆盖视图控制器的其余部分。

希望这可以帮助!

于 2013-10-09T13:49:45.560 回答
33

导航栏离状态栏太近了,因为从 iOS 7 开始,状态栏更像是覆盖在整个视图控制器的视图上。由于您的导航栏位于 (0, 0),因此状态栏将显示在导航栏的顶部。要解决这个问题,只需将导航栏向下移动(或者,正如其他人所说),在导航栏和 topLayoutGuide 之间创建一个约束。

当你这样做时,你会看到导航栏和屏幕顶部之间现在有 20 点的差距。那是因为您刚刚将导航栏向下移动了 20 点。“可是UINavigationController能做对!” 绝对可以,它通过UIBarPositioningDelegate在您的视图控制器上实现来实现。这是一个单一方法的协议,应该像这样实现:

- (UIBarPosition)positionForBar:(id<UIBarPositioning>)bar {
    return UIBarPositionTopAttached;
}

将视图控制器添加为导航栏的代理后,您会注意到导航栏仍向下移动了 20 点,但其背景将在状态栏下方向上延伸,就像在UINavigationController.

您看到的另一件事是导航栏是半透明的,这意味着导航栏下方的任何内容都会在某种程度上可见。在iOS 7 上,ontranslucent属性默认UINavigationBar设置为YES。在 iOS 7 之前,默认值为NO.

于 2013-10-03T15:14:09.663 回答
4

你可以简单地这样做:

1)在导航栏顶部布局指南之间添加一个约束(选择导航栏,按住 ctrl 键并转到底部布局指南,取消按住 ctrl 键)

添加垂直约束

2)选择垂直间距

垂直间距

3) 将常量设置为0

垂直间距常数

结果:

结果

更新

在您的 AppDelegate 文件中,您可以添加以下内容:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool 
{
  // Prevent Navigationbar to cover the view
  UINavigationBar.appearance().translucent = false
}
于 2015-03-09T16:16:09.143 回答
3

我建议你在你的 viewDidLoad 方法中尝试:

self.navigationController.navigationBar.translucent = NO;

(默认情况下是现在)

https://developer.apple.com/library/ios/documentation/uikit/reference/UINavigationBar_Class/Reference/UINavigationBar.html#//apple_ref/occ/instp/UINavigationBar/translucent

于 2013-10-03T15:00:47.700 回答
2

这对我有用,我希望你也有同样的运气:)。
在您的视图中添加以下代码。

-(void) viewDidLayoutSubviews
{
    CGRect tmpFram = self.navigationController.navigationBar.frame;
    tmpFram.origin.y += 20;
    self.navigationController.navigationBar.frame = tmpFram;
}

它基本上改变了导航栏的位置。

于 2013-10-03T14:44:01.530 回答
2

首先,UIViewControllerBasedStatusBarAppearance在 Info.plist 中设置为 NO。然后,在AppDelegate'sapplication:didFinishLaunchingWithOptions:方法中添加:

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;
于 2013-10-07T13:12:14.920 回答
2

这是IOS7的新功能。而不是在 IOS7 中盯着 20 px 的导航栏盯着 0 px。作为一种解决方案,将整个视图向下移动到 20 像素,或者您可以将图像用于高度为 64 像素的导航栏。

于 2013-10-09T10:00:30.030 回答
2

如果它仍然对某人有帮助,这对我在 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;
}
于 2014-04-24T05:15:37.420 回答
2

如果您不在UIViewControllera 中UINavigationController并且您正在使用UIStoryBoard,则可以将增量 Y 的“iOS 6/7 Deltas”设置为 20,对于需要从UIStatusBar.

在此处输入图像描述

于 2014-10-07T22:15:00.967 回答
2

使用斯威夫特

正如@Scott Berrevoets 在他的回答中所说,您需要positionForBar在协议中实现该方法UIBarPositioningDelegate,但由于UINavigationBarDelegate协议实现了此协议:

public protocol UINavigationBarDelegate : UIBarPositioningDelegate {
   ...
}

您只需要使用 Storyboard 设置您设置的delegateUINavigationBar实现该方法即可完成,就像这样:

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您需要的行为从顶部设置为 20。

我希望它会帮助你。

于 2016-04-14T20:46:14.397 回答
1

在 iOS 7 应用程序占据 100% 的屏幕大小。这不是问题。 http://www.doubleencore.com/2013/09/developers-guide-to-the-ios-7-status-bar/

于 2013-10-07T12:42:26.353 回答
1

在早期的 iO​​S 窗口中,在状态栏之后开始,在 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。试试下面的代码,它会帮助你。你的问题就会得到解决。

于 2013-10-09T08:23:28.230 回答
1

对于那些在实施@Masterfego 的解决方案时遇到问题的人(这也是官方的,但我在 Xcode 6.3 和自动约束方面遇到了问题),这就是我所做的:

我有一个带有导航栏的 UIViewController。我选择了导航栏并添加了 64 像素的高度约束。我们稍后会看到导航栏会更高的警告(但这就是我们所做的)。最后,您可以看到状态栏看起来不错,并且与导航栏颜色相同。:)

PS:我还不能发图片。

于 2015-04-28T14:16:52.067 回答
0

您可能可以创建附加到顶部布局指南的约束,以指定导航栏相对于状态栏的位置。有关使用布局指南的更多信息,请参阅iOS 7 UI 转换指南:外观和行为部分

于 2013-10-01T00:00:57.033 回答
0

这是最好的答案。但我想知道如何使用 aStoryboardUINavigationBar坚持下去。当我实现委托方法并将返回结果设置为 时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;
}
于 2013-11-27T07:30:22.047 回答
0

如果你使用 Xcode 6 和 Swift,你可以做到:

  1. 打开应用程序的 info.plist 文件。
  2. 添加一个 ViewControllerBasedStatusBarAppearance 布尔键,如果它不存在并赋值“NO”。
  3. 如果它不存在,则添加“状态栏样式”键并为其选择“不透明黑色样式”值。
于 2015-03-23T01:50:43.223 回答
0

从我的全屏ModalViewController打开时我遇到了问题,当用户返回MainViewController时位置NavigationBar正在改变MainViewControllerModalViewController

我注意到的问题是当用户返回MainViewController. 请NavigationBar在返回您的ViewController.

// This method will adjust navigation bar and view content.
    private func adjustNavigationControllerIfNeeded() {

        var frame = self.view.frame
        let navigationBarHeight = self.navigationController!.navigationBar.frame.size.height

        if(frame.origin.y == navigationBarHeight && !UIApplication.shared.isStatusBarHidden) { 

   // If status bar height is not included but it is showing then we have to adjust 
      our Navigation controller properly

            print("Adjusting navigation controller")
            let statusBarHeight = UIApplication.shared.statusBarFrame.height

            frame.origin.y += statusBarHeight // Start view below navigation bar
            frame.size.height -= statusBarHeight
            self.view.frame = frame

            self.navigationController!.navigationBar.frame.origin.y = statusBarHeight // Move navigation bar
        }
    }

并从 viewWillAppear 方法调用它 -

override func viewWillAppear(_ animated: Bool) {

        super.viewWillAppear(animated)
        self.adjustNavigationControllerIfNeeded()
}
于 2018-03-07T06:33:14.703 回答