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 之前 ,可以看到视图的边界发生了变化。

viewWillLayoutSubviewsviewDidLayoutSubviews方法是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; }