【问题标题】:UIViewController wrong height on initial loadUIViewController 初始加载时高度错误
【发布时间】:2015-11-06 20:47:45
【问题描述】:

我在 iOS 7 和 8 上运行的应用在 iOS9 上遇到了一些小问题,其中一个是单个视图控制器的高度错误。

以下代码:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self layoutViews];
}

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
    [self layoutViews];
}

- (void)layoutViews {
    NSLog(@"Size-> %@", NSStringFromCGRect(self.view.frame));
}

产生以下错误输出:

2015-11-06 22:42:31.737 app[62442:1136052] Size-> {{0, 0}, {375, 667}}
2015-11-06 22:42:33.318 app[62442:1136052] Size-> {{0, 32}, {667, 343}}
2015-11-06 22:42:34.885 app[62442:1136052] Size-> {{0, 64}, {375, 603}}
2015-11-06 22:45:18.063 app[62442:1136052] Size-> {{0, 32}, {667, 343}}

当我:

  1. 纵向打开 VC
  2. 旋转到横向
  3. 转回纵向
  4. 转回横向

似乎 VC 的初始加载在self.frame.size 下提供了错误的大小,而所有后续轮换都是正确的。 603 的高度是正确的,但是您可以看到,在两次旋转到横向时,667 的高度仍然不正确。

我认为与导航控制器栏有关的某些事情可能会破坏它。我在viewDidLoad 方法中的代码很简单:

- (void)viewDidLoad {
    if ([self respondsToSelector:@selector(edgesForExtendedLayout)]) {
        [self setEdgesForExtendedLayout:UIRectEdgeNone];
    }

    [super viewDidLoad];
}

这在 iOS 8 上运行良好。

更新 通过添加对viewDidAppear 的调用来解决此问题:

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    [self layoutViews];
    [activitiesTable flashScrollIndicators];
}

【问题讨论】:

  • 您是否启用了状态栏?
  • 是的,我一直有状态栏。

标签: ios objective-c iphone uiviewcontroller ios9


【解决方案1】:

您的代码是正确的,并且在第一次加载后可以完美运行。

所以第一次加载应用程序的问题。

Apple Document for Auto layout 提供了答案。

您只需要在viewDidAppear: 方法中编写代码。

所以把你的代码从viewDidLoad:方法写到

-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated]; }

【讨论】:

  • 我什至试过这个。我在加载时调用了 setEdgesForExtendedLayout 并确实出现了,它给了我相同的结果!!!!
  • 这行得通,我忽略了viewDidAppear 方法。在 iOS9 中,必须额外触发 viewDidAppear 中的 layoutViews 自定义方法。这显示了 iOS9 中行为的明显差异,但是嘿.. 我们已经习惯了 ;)
【解决方案2】:

我不确定您为什么要在 viewDidLoad 中添加 setEdgesForExtendedLayout。我尝试了您的方式

UIRectEdgeNone:

2015-11-06 19:40:41.881 Test[934:275179] Size-> {{0, 64}, {375, 603}}

我的视图控制器上有导航栏。

UIRectEdgeTop && UIRectEdgeAll:

2015-11-06 19:52:18.086 Test[1113:331687] Size-> {{0, 0}, {375, 667}}

UIRectEdgeLeft && UIRectEdgeBottom && UIrectEdgeRight && UIRectEdgeNone:

2015-11-06 19:54:43.864 Test[1137:343893] Size-> {{0, 64}, {375, 603}}

如文档中所述:

在 iOS 7 中,视图控制器使用全屏布局。同时,iOS 7 让您可以更精细地控制视图控制器布局其视图的方式。特别是,全屏布局的概念得到了改进,让视图控制器可以指定其视图每个边缘的布局。

WantsFullScreenLayout 视图控制器属性在 iOS 7. 如果您当前指定 WantsFullScreenLayout = NO,则视图 控制器可能会在意外的屏幕位置显示其内容 当它在 iOS 7 中运行时。

使用 edgesForExtendedLayout 来指定视图的哪些边缘应该被扩展,而不管条形半透明。默认情况下,该属性的值为 UIRectEdgeAll。

如果你在UIRectEdgeAll vs UIRectEdgeNone 的情况下查看调试器

如果你使用 UIRectEdgeAll,视图控制器视图使用全屏布局:

如果你使用 UIRectEdgeNone,视图控制器将不会使用全屏布局,它会将视图向右推向导航栏的底部:

我建议使用UIEdgeRectAll 而不是UIEdgeRectNone,除非你真的想组织所有子视图的框架,包括你的视图控制器视图!!!

【讨论】:

  • 使用 UIEdgeRectNone 没有任何问题。默认值是 UIRectEdgeAll 因为默认行为是一个半透明的导航栏,内容显示在下面。使用不透明导航栏时,在其下方显示内容是有意义的。
  • 我使用 UIRectEdgeNone 来解决视图在导航栏下移动带来的烦恼 - 到目前为止,这是我以编程方式找到的最简单的方法。令人困惑的是为什么我的示例在旋转后 更改 高度。我不太介意它的行为方式,只要它是一致的。以您的 UIRectEdgeLeft + UIRectEdgeRight + UIRectEdgeBottom + UIRectEdgeNone 的示例,我得到 667 高、667 长(旋转)、603 高(旋转),这与我之前得到的相同。无论我在那里设置什么,高度都不一致..
  • 我明白了,很抱歉造成混乱。不幸的是,问题不在于edgeForExtendedLayout,而在于@maulik-patel 建议的viewDidAppear。感谢您的详细回答!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-12-06
  • 2016-11-19
  • 2016-03-01
  • 1970-01-01
  • 2010-12-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多