UIViewController返回无效帧? [英] UIViewController returns invalid frame?

查看:104
本文介绍了UIViewController返回无效帧?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

When I start my ViewController in landscape mode (After viewDidLoad is called), I print the frame it's giving me the frame size for portrait mode instead.

这是一个bug有什么建议吗?

Is this a bug any suggestions?

- (void)viewDidLoad
{
   [super viewDidLoad];

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


推荐答案

有几件事情你不明白。

首先,系统发给你 viewDidLoad 。它甚至没有将视图添加到视图层次结构中。因此它没有根据设备的旋转调整视图大小。

First, the system sends you viewDidLoad immediately after loading your nib. It hasn't even added the view to the view hierarchy yet. So it hasn't resized your view based on the device's rotation either.

其次,视图的框架位于其superview的坐标空间中。如果这是您的根视图,则其超级视图将是 UIWindow (一旦系统实际将视图添加到视图层次结构中)。 UIWindow 通过设置其子视图的变换来处理旋转。这意味着视图的框架不一定是您所期望的。

Second, a view's frame is in its superview's coordinate space. If this is your root view, its superview will be the UIWindow (once the system actually adds your view to the view hierarchy). The UIWindow handles rotation by setting the transform of its subview. This mean that the view's frame will not necessarily be what you expect.

以下是纵向视图层次结构:

Here's the view hierarchy in portrait orientation:

(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>>

这里是横向左方向的视图层次结构:

and here's the view hierarchy in landscape-left orientation:

(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。

Notice that in landscape orientation, the frame size is 748 x 1024, not 1024 x 748.

你可能想看一下,如果这是你的根视图,那就是视图的界限:

What you probably want to look at, if this is your root view, is the view's bounds:

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

大概你想知道视图转换的时间,框架,边界得到更新。如果视图控制器加载其视图时界面处于横向,您将按以下顺序接收消息:

Presumably you want to know when the view's transform, frame, and bounds get updated. If the interface is in a landscape orientation when your view controller loads its view, you will receive messages in this order:

{{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:

您可以看到之后您的视图边界发生了变化 eceive willRotateToInterfaceOrientation:duration: 之前收到 viewWillLayoutSubviews

You can see that your view's bounds change after you receive willRotateToInterfaceOrientation:duration: and before you receive viewWillLayoutSubviews.

viewWillLayoutSubviews viewDidLayoutSubviews 方法是iOS 5.0的新功能。

The viewWillLayoutSubviews and viewDidLayoutSubviews methods are new to iOS 5.0.

layoutSubviews 消息发送到视图,而不是视图控制器,因此您需要创建自定义 UIView 子类,如果你想使用它。

The layoutSubviews message is sent to the view, not the view controller, so you will need to create a custom UIView subclass if you want to use it.

这篇关于UIViewController返回无效帧?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆