旋转后的UIView坐标交换,但UIWindow的不是?

使用Xcode 4.2.1 iPad iOS 5.0.1,创build一个新的“Single View”iPad项目。 在控制器中添加:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return YES; } - (void) dumpView: (UIView *) view { CGRect frame = view.frame ; CGRect bounds = view.bounds ; CGPoint center = view.center ; NSLog(@"view [%@]:%d frame=%@ bounds=%@ center=%@" , NSStringFromClass(view.class) , [view hash] , NSStringFromCGRect(frame) , NSStringFromCGRect(bounds) , NSStringFromCGPoint(center)) ; } - (void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation) fromInterfaceOrientation { NSLog(@"INViewController.didRotateFromInterfaceOrientation: %d to %d", fromInterfaceOrientation, self.interfaceOrientation) ; [self dumpView: self.view] ; [self dumpView: self.view.superview] ; } 

运行它,旋转设备,你会得到:

 INViewController.didRotateFromInterfaceOrientation: 2 to 4 view [UIView] bounds={{0, 0}, {1024, 748}} center={394, 512} view [UIWindow] bounds={{0, 0}, {768, 1024}} center={384, 512} 

换句话说,UIView的坐标“交换到风景”的预期,但其父UIWindow仍然声称是肖像模式…

此外,UIView大小似乎有点错误:应该是在20的y坐标是0 …

有人知道这是什么意思?

UIWindow的坐标系始终是纵向的。 它通过设置其rootViewController视图的变换来应用旋转。 例如,我使用单视图模板创build了一个testing应用程序并运行它。 纵向:

 (gdb) po [[(id)UIApp keyWindow] recursiveDescription] <UIWindow: 0x9626a90; frame = (0 0; 768 1024); layer = <UIWindowLayer: 0x9626b80>> | <UIView: 0x96290e0; frame = (0 20; 768 1004); autoresize = W+H; layer = <CALayer: 0x96286a0>> 

左转后:

 (gdb) po [[(id)UIApp keyWindow] recursiveDescription] <UIWindow: 0x9626a90; frame = (0 0; 768 1024); layer = <UIWindowLayer: 0x9626b80>> | <UIView: 0x96290e0; frame = (0 0; 748 1024); transform = [0, 1, -1, 0, 0, 0]; autoresize = W+H; layer = <CALayer: 0x96286a0>> 

右转后:

 (gdb) po [[(id)UIApp keyWindow] recursiveDescription] <UIWindow: 0x9626a90; frame = (0 0; 768 1024); layer = <UIWindowLayer: 0x9626b80>> | <UIView: 0x96290e0; frame = (20 0; 748 1024); transform = [0, -1, 1, 0, 0, 0]; autoresize = W+H; layer = <CALayer: 0x96286a0>> 

注意旋转设备时如何设置变换(到90度旋转matrix)。

关于你关于UIView大小的问题:一个视图的边界在它自己的坐标空间中,默认情况下视图边界的原点位于其坐标空间的原点(0,0)处。 一个视图的框架在其父节点的坐标空间中。 您可以在上面的recursion描述中看到您期待的20个,或者直接打印框架:

 (gdb) p (CGRect)[[[[(id)UIApp keyWindow] subviews] lastObject] frame] $2 = { origin = { x = 0, y = 20 }, size = { width = 768, height = 1004 } }