IOS开发:关于在恰当的地方初始化界面设置layout

参考http://stackoverflow.com/questions/9539676/uiviewcontroller-returns-invalid-frame/9540935#9540935,先记下来:

Is this a bug any suggestions?

- (void)viewDidLoad
{
   [super viewDidLoad];

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


There are a couple of things that you don't understand.

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.

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

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:

You can see that your view's bounds change after you receivewillRotateToInterfaceOrientation:duration: and before you receiveviewWillLayoutSubviews.

The viewWillLayoutSubviews and viewDidLayoutSubviews methods are new to iOS 5.0.

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.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值