UIViewController返回无效的框架?
当我以landscape
模式启动我的ViewController(在调用viewDidLoad之后)时,我打印它给框架大小的肖像模式。
这是一个错误的任何build议?
- (void)viewDidLoad { [super viewDidLoad]; NSLog(@"%@", NSStringFromCGRect(self.view.frame)); // Result is (0, 0 , 768, 1024) }
有一些你不明白的东西。
首先,系统在加载你的笔尖后立即向你发送viewDidLoad
。 它甚至没有将视图添加到视图层次结构中。 所以它还没有根据设备的旋转调整视图的大小。
其次,一个视图的框架在其超视图的坐标空间中。 如果这是你的根视图,它的超级视图将是UIWindow
(一旦系统实际上将你的视图添加到视图层次结构中)。 UIWindow
通过设置子视图的变换来处理旋转。 这意味着观点的框架不一定是你所期望的。
这是纵向的视图层次结构:
(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>>
这里是横向左侧的视图层次结构:
(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。
如果这是您的根视图,您可能要查看的是视图边界:
(lldb) p (CGRect)[0x9634ee0 bounds] (CGRect) $3 = { (CGPoint) origin = { (CGFloat) x = 0 (CGFloat) y = 0 } (CGSize) size = { (CGFloat) width = 1024 (CGFloat) height = 748 } }
假设你想知道什么时候视图的变换,帧和边界得到更新。 如果当您的视图控制器加载视图时界面处于横向模式,您将按以下顺序接收消息:
{{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:
在收到willRotateToInterfaceOrientation:duration:
, 在收到viewWillLayoutSubviews
之前 ,可以看到视图的边界发生了变化。
viewWillLayoutSubviews
和viewDidLayoutSubviews
方法是iOS 5.0的新增function。
layoutSubviews
消息被发送到视图,而不是视图控制器,所以如果你想使用它,你将需要创build一个自定义的UIView
子类。
这是一个干净的解决scheme。
我遇到了同样的问题,我坚持在整个应用程序中使用frame
。 我不想为根视图控制器创build一个例外。 我注意到根视图控制器的frame
显示纵向尺寸, 但所有子视图都有正确的横向尺寸 。
由于只有根视图控制器的行为不同,我们可以将一个标准的空白视图控制器设置为根视图控制器,并添加我们的自定义视图控制器。 (代码如下)
然后,您可以在自定义视图控制器中使用frame
。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; // Override point for customization after application launch. self.window.rootViewController = [[UIViewController alloc] init]; [self.window makeKeyAndVisible]; self.viewController = [[ViewController alloc] initWithNibName:nil bundle:nil]; [self.window.rootViewController addChildViewController:self.viewController]; [self.window.rootViewController.view addSubview:self.viewController.view]; return YES; }