当我在 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
.
viewWillLayoutSubviews
和 viewDidLayoutSubviews
方法是 iOS 5.0 的新方法。
layoutSubviews
消息被发送到 View ,而不是 View Controller ,所以如果你想使用它,你需要创建一个自定义的 UIView
子类。
关于ios - UIViewController 返回无效的框架?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9539676/