【问题标题】:iPhone UIViewController goes under status bariPhone UIViewController 进入状态栏
【发布时间】:2010-12-24 16:17:52
【问题描述】:

我有一个UIView 和一个UIController 视图。我的是标准的 320x460 视图。在applicationDidFinishLaunching 我愿意:

[window addSubview:[controller view]];

奇怪的是UIView 位于状态栏下方(就像缺少插座一样)。但是,如果我将 iPhone 旋转到一边然后再旋转回来,它会显示正常。

这是一种预期的行为(我敢打赌我可以通过设置偏移来修复它)还是我做错了什么?

【问题讨论】:

  • 试试模拟界面元素?
  • 我在窗口、控制器和视图上启用了模拟状态栏 - 运气不好...当应用程序在 iPhone 中启动或在 XCode 中启动模拟器时,布局已损坏。但是,它在 InterfaceBuilder 的模拟器中运行良好

标签: iphone ios objective-c layout uiviewcontroller


【解决方案1】:

我在通过 presentModalViewController 显示 UIViewController 时遇到了这个问题。

您可以通过手动调整控制器视图的大小来解决它视图出现后:

- (void) viewDidAppear: (BOOL) animated {
    //manually adjust the frame of the main view to prevent it from appearing under the status bar.
    UIApplication *app = [UIApplication sharedApplication];
    if(!app.statusBarHidden) {
        [self.view setFrame:CGRectMake(0.0,app.statusBarFrame.size.height, self.view.bounds.size.width, self.view.bounds.size.height - app.statusBarFrame.size.height)];
    }
}

【讨论】:

  • 跟进:我见过的最好的解决方案是为您的视图控制器打开 nib 文件,选择主视图,然后在“模拟用户界面元素”下设置“状态栏”选项除了“未指定”之外的任何内容。我无法解释正在更改哪些内部值,只是这解决了我的应用程序的问题。如果您这样做,您将不需要我之前回答中的代码。
  • app.statusBarFrame.size.height 返回 0。:(
  • 更正(根据我的评论): [[UIApplication sharedApplication] statusBarFrame].size.height 如果在以下内容之前执行,则返回 0: [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:NO];但在那之后,它返回 20。 statusbarHeight = [[UIApplication sharedApplication] statusBarFrame].size.height; // statusbarHeight == 20
【解决方案2】:

我认为你的问题是,当你在窗口中添加视图时,你需要了解状态栏的状态并进行补偿:

if showing the status bar :
   [controller view].frame = CGRectMake(0, **20**, 320, 460);
else 
   [controller view].frame = CGRectMake(0, 0, 320, **480**);

这就是 IB 向您显示虚拟状态栏的原因。

【讨论】:

  • 谢谢。我已经在使用它来解决问题。我只是不确定这是否是解决问题的传统方法。
  • 很好的解决方法,但请注意,20 应该是 CGRectMake 的第二个参数,而不是第一个 :)。
【解决方案3】:

我今天添加了这个问题。事实证明,我在 ViewController 的属性检查器中检查了“想要全屏”。

关闭“想要全屏”解决了这个问题。

【讨论】:

    【解决方案4】:

    最后,我得到了这个解决方案。 适用于 iPhone 和 iPad

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
    
        self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
    
        // Allocate view controller and load nib file
        if (isIPhone) {
            self.mainViewController = [[[tfdMainViewController_iPhone alloc] initWithNibName:@"tfdMainViewController_iPhone" bundle:nil] autorelease];
        } else {
            self.mainViewController = [[[tfdMainViewController_iPad alloc] initWithNibName:@"tfdMainViewController_iPad" bundle:nil] autorelease];
        }
    
        // Offset correction (iPhone bug?)
        CGRect r = self.mainViewController.view.frame; 
        r = CGRectOffset(r, 0, [UIApplication sharedApplication].statusBarFrame.size.height);
        [self.mainViewController.view setFrame:r];  
    
        [window addSubview: self.mainViewController.view];
        [self.window makeKeyAndVisible];
        return YES;
    }
    

    附:由于某种原因,视图具有正确的高度: 480(iPhone 纵向模式下的屏幕高度)- 20(状态栏)= 460, 但未能设置垂直偏移。这是非常奇怪的行为,看起来像错误。

    【讨论】:

      【解决方案5】:

      对窗口的修复对我不起作用,因为我有一个模态视图。 UIModalPresentationCurrentContext 模式视图。好的,这对我有用。在使它起作用之前,我一直在上下搜索网络。 我无法从父级移动 view.frame。但是在 viewWillAppear 中,我可以将其向下移动:

      - (void)viewWillAppear:(BOOL)animated
      {
          // Move down to compensate for statusbar
          CGRect frame = parentView.navCon.view.frame;
          frame.origin.y = [UIApplication sharedApplication].statusBarFrame.size.height;
          parentView.navCon.view.frame = frame;
      }
      

      【讨论】:

      • 那是“作弊”! ;-) 你应该“找到”状态栏的高度,而不是“硬编码”为 20。如果 Apple 决定将其更改为 25,该怎么办?然后你会离开 5px!
      【解决方案6】:

      如果您使用的是 Interface Builder 的“模拟用户界面元素”,那么您还需要确保在 MainWindow nib 中设置了“Resize View From NIB”的标志。

      【讨论】:

        【解决方案7】:

        这似乎是 iOS 5 中的一个错误。一种修复方法是在任何需要以模态方式呈现的视图控制器中使用 wantsFullScreenLayout,并手动将视图布局始终位于状态栏下方。

        http://www.cocoanetics.com/2012/06/radar-view-frame-inconsistency-using-presentviewcontroller-wantsfullscreenlayout-yn/

        http://openradar.appspot.com/radar?id=1758406

        【讨论】:

          【解决方案8】:

          您是否在添加子视图后手动设置应用程序栏隐藏属性?我不认为是这种情况,但是如果在您第一次加载视图时将其设置为无,它将像没有视图一样进行布局,如果您随后将状态栏设置为不隐藏,它将弹出在顶部你的看法。

          一个可能的解决方案是在添加子视图后使用[[controller view] setNeedsLayout];,或者可能是[window layoutSubviews];。使用它们来解决布局问题我从来没有取得过很多成功,但由于它在旋转后工作,所以值得一试。

          【讨论】:

          • 我不会在任何时候隐藏应用程序栏。那些重新布局的东西没有帮助......
          【解决方案9】:

          即使我也遇到了同样的问题。当我们为设备方向使用一些编码时,我们已经在应用程序委托或我们的视图控制器中编写了一些编码。在那里我们需要更改条件以使用方向返回 YES 或 NO。这解决了我们的问题。

          【讨论】:

            【解决方案10】:

            我更喜欢使用 UINavigationController 来包装 UIViewController,然后将 NavigationBarHidden 设置为 UINavigationController。这是完美的解决方案,因为 UINavigationController 确实在 iOS 7 中处理状态栏的高度。

            这是我的代码和屏幕截图。

            UINavigationController *wrapNavController = [[UINavigationController alloc] initWithRootViewController:yourViewController] ;
            
            [wrapNavController setNavigationBarHidden:YES] ;
            

            【讨论】:

              【解决方案11】:

              Xcode 6、iOS7/8 的解决方案是取消选中 Attributes Inspector 的 View Controller 部分的“Extend Edges”部分中的“Under Top Bars”复选标记。

              【讨论】:

                【解决方案12】:

                对于 Xamarin.iOS,它将是:

                if (UIApplication.SharedApplication.StatusBarHidden == false)
                {
                   var statusBarHeight = UIApplication.SharedApplication.StatusBarFrame.Height;
                   View.Frame = new CoreGraphics.CGRect(0, statusBarHeight, View.Frame.Width, View.Frame.Height - statusBarHeight);
                }
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2017-09-21
                  • 2017-11-08
                  • 1970-01-01
                  • 2023-04-03
                  • 2011-06-14
                  • 1970-01-01
                  • 2014-11-06
                  • 1970-01-01
                  相关资源
                  最近更新 更多