ios - UIViewController 返回无效的框架?

标签 ios uiviewcontroller landscape

当我在 landscape 模式下启动我的 ViewController 时(在调用 viewDidLoad 之后),我打印了框架,它给我提供了纵向模式的框架大小。

这是一个错误有什么建议吗?

- (void)viewDidLoad
{
   [super viewDidLoad];

   NSLog(@"%@", NSStringFromCGRect(self.view.frame));
   // Result is (0, 0 , 768, 1024)
}

最佳答案

有几件事你不明白。

首先,系统在加载您的 nib 后立即向您发送 viewDidLoad。它甚至还没有将 View 添加到 View 层次结构中。所以它也没有根据设备的旋转调整 View 的大小。

其次, View 的框架位于其父 View 的坐标空间中。如果这是您的 Root View ,它的 super View 将是 UIWindow(一旦系统实际将您的 View 添加到 View 层次结构中)。 UIWindow 通过设置其 subview 的变换来处理旋转。这意味着 View 的框架不一定是您所期望的。

这是纵向 View 层次结构:

(lldb) po [[UIApp keyWindow] recursiveDescription]
(id) $1 = 0x09532dc0 <UIWindow: 0x9632900; frame = (0 0; 768 1024); layer = <UIWindowLayer: 0x96329f0>>
   | <UIView: 0x9634ee0; frame = (0 20; 768 1004); autoresize = W+H; layer = <CALayer: 0x9633b50>>

这是横向左方向的 View 层次结构:

(lldb) po [[UIApp keyWindow] recursiveDescription]
(id) $2 = 0x09635e70 <UIWindow: 0x9632900; frame = (0 0; 768 1024); layer = <UIWindowLayer: 0x96329f0>>
   | <UIView: 0x9634ee0; frame = (20 0; 748 1024); transform = [0, -1, 1, 0, 0, 0]; autoresize = W+H; layer = <CALayer: 0x9633b50>>

请注意,在横向模式下,框架大小为 748 x 1024,不是 1024 x 748。

如果这是您的 Root View ,您可能想要查看的是 View 的边界:

(lldb) p (CGRect)[0x9634ee0 bounds]
(CGRect) $3 = {
  (CGPoint) origin = {
    (CGFloat) x = 0
    (CGFloat) y = 0
  }
  (CGSize) size = {
    (CGFloat) width = 1024
    (CGFloat) height = 748
  }
}

您可能想知道 View 的转换、框架和边界何时更新。如果当您的 View Controller 加载其 View 时界面处于横向方向,您将按以下顺序接收消息:

{{0, 0}, {768, 1004}} viewDidLoad
{{0, 0}, {768, 1004}} shouldAutorotateToInterfaceOrientation:
{{0, 0}, {768, 1004}} shouldAutorotateToInterfaceOrientation:
{{0, 0}, {768, 1004}} viewWillAppear:
{{0, 0}, {768, 1004}} shouldAutorotateToInterfaceOrientation:
{{0, 0}, {768, 1004}} shouldAutorotateToInterfaceOrientation:
{{0, 0}, {768, 1004}} willRotateToInterfaceOrientation:duration:
{{0, 0}, {1024, 748}} viewWillLayoutSubviews
{{0, 0}, {1024, 748}} layoutSubviews
{{0, 0}, {1024, 748}} viewDidLayoutSubviews
{{0, 0}, {1024, 748}} willAnimateRotationToInterfaceOrientation:duration:
{{0, 0}, {1024, 748}} shouldAutorotateToInterfaceOrientation:
{{0, 0}, {1024, 748}} viewDidAppear:

您可以看到 View 的边界发生变化您收到willRotateToInterfaceOrientation:duration:之前您收到viewWillLayoutSubviews.

viewWillLayoutSubviewsviewDidLayoutSubviews 方法是 iOS 5.0 的新方法。

layoutSubviews 消息被发送到 View ,而不是 View Controller ,所以如果你想使用它,你需要创建一个自定义的 UIView 子类。

关于ios - UIViewController 返回无效的框架?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9539676/

相关文章:

java - 如何在 Android 应用程序中阻止或改善横向 View

ios - 无需重新压缩即可从用户图库保存/获取 JPEG

ios - 单击提交按钮后从 ortuman/Swift Forms 检索数据

iOS - 转场和静态单元格

ios - 重置 UITabBarController 上的导航堆栈不起作用

ios - 横向导航 Controller ,弹出向上滚动

android - 如何为纵向和横向指定不同的布局?

ios - 师生应用;移动设备之间的通信

ios - CoreData 与否与 Restkit

ios - 从 Storyboard实例化的 UIViewController 扩展