今天遇到一个很郁闷的问题:新做的ipad程序中,界面居然在未作任何配置的情况下不支持旋转了。
通过在UITabbarController
的旋转事件添加NSLog
发现,其完全没有被触发。通过网上查资料 在cocochina
上找到了答案:
是位
hanzengbo
的朋友的解答 原文如下:
“昨天忙乎了一天,没搞定。今天早上终于搞定了。贴出来希望能对遇到相似问题的哥们有用。前面搜到的答案都说是UITabbarController
的问题。但是我重新写了个小程序,也使用了tabbar
这个控件,发现每个窗体也是能触发旋转事件的。昨天在tabbarcontroller
这个地方弄了一天,一直没有弄成功。但是有一点可以肯定,就是旋转事件是被父窗体劫持了,从而使得tabbar中的每个窗体不能接受到旋转事件。今天来重新看了一下程序,发现问题在于我的程序开始有个启动窗体,在delegate
文件中,我把tabbarcontroller
的view
加进了这个启动窗体,所以整个程序的父窗体就是这个启动窗体。我在启动窗体的旋转事件中打印log
信息,能够成功。为了让tabbar
的每个view
能够响应旋转事件,就只能让他们成为单独的父窗体。所以我修改启动窗体代码,首先在delegate
中addsubview
启动窗体,然后addsubview tabbar
的窗体,在启动画面显示一定时间后,就把启动窗体从window
中remove
掉,这样下面的tabbar
窗体就显示出来了,而且tabbar
的窗体成为了父窗体,能够正常接受到旋转时间。”
和我一样,我也有登录窗 嘿嘿 太巧了
[[[self.view.superview subviews] objectAtIndex:0] removeFromSuperView];
搞定 。
界面正常了 。iOS
要学的东西真很多,为自己鼓劲 特此记录
注:
要翻转的时候,首先响应的方法:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
return YES;//则支持翻转,NO则不支持。
紧接着
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{
}
被调用。这个方法是发生在翻转开始之前。一般用来禁用某些控件或者停止某些正在进行的活动,比如停止视频播放。 再来是
-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{
}
这个方法发生在翻转的过程中,一般用来定制翻转后各个控件的位置、大小等。可以用另外两个方法来代替:willAnimateFirstHalfOfRotationToInterfaceOrientation:duration:
和 willAnimateSecondHalfOfRotationFromInterfaceOrientation:duration:
最后调用的是
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation{
}
这个方法发生在整个翻转完成之后。一般用来重新启用某些控件或者继续翻转之前被暂停的活动,比如继续视频播放。
UIViewController没有随着设备一起旋转的原因
对于iPhone app
,UIViewController
类提供了基本的视图管理模式。当设备改变方向的时候view controller
的视图会自动随之旋转的。如果视图和子视图的autoresizing
属性设置是对的,这时候视图又没有随着设备一起旋转,可能是以下的原因:
1.view controller
没有完成代理方法
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{
return YES;
}
也要实现了shouldAutorotateToInterfaceOrientation
方法,同时shouldAutorotateToInterfaceOrientation
方法要返回YES
来支持所有的旋转方向
2.view controller
的UIView
属性嵌入在UIWindow
中,并非是一个附加的view controller
你可能会发现shouldAutorotateToInterfaceOrientation
方法只会在view controller
启动的时候被调用,不会因为设置的旋转而在被调用。这是因为view controller
束缚着他们所管理的视图,view controller
是用来处理时间的响应链的一部分。view controller
是从UIResponder
继承而来,同时他被插入到他所管理的视图和他的superview
之间。因此,通常的做法是在你的app
中有一个主view controller
来作为响应链的一部分。通常来说会添加一个主view controller
,例如UINavigationController
, UITabBarController
或者UIViewController
到UIWindow
上。
例如:
[myWindow addSubview:primaryViewController.view];
如果你添加了另外一个view controller的UIView
属性到UIWindow
(anotherController
和主view controller
在同一个等级上)
[myWindow addSubview:anotherController.view];
anotherController
将不会接受旋转事件,只有第一个view controller
(primaryViewController
)会接受旋转事件。
3.你添加了view controller
的UIView
属性到UIWindow
作为subview
,但是过早的release
它。
UIWindow会retain
视图,而不是view controller
。你不能过早的release
他。在UIApplicationDelegate子
类中定义他为retain
属性。
4.在UITabBarController
或者UINavigationController
中的子view controller
没有对同一方向的支持。
为了确保所有的子view controller
旋转正确,你的每一个view controller
,每一个tab
或者额navigation
都要完成shouldAutorotateToInterfaceOrientation
,而且必须支持对于同一方向的旋转,也就是说对于同一方向的位置要返回为YES
。
5.重写-(id)init:
或者 -(id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)nibBundle
方法的时候没有调用super
。
对于对象的初始化,在你的view controller
的init
或者initWithNibName
方法中必须要调用super
。
iphone
提供了优秀的重力加速计,能够很灵敏地感应到手机的屏幕状态。在我们开发iphone
应用时,为了提高用户体验,会来监听屏幕的当前状态。
对于
UIViewController
来说,提供了好几种方法。
- 最简单的就是我们可以使用
Interface Builder
这个工具来帮助我们实现简单的屏幕界面适配,只需要在IB
中的Size Insepector
中通过对Autosizing
的 设置来实现。但这只能做到简单界面的实现,如果界面比较复杂,可能就需要我们通过代码来实现。- 我们可以通过对
willAnimateRotationToInterfaceOrientation:duration:
这个方法的重写来配置我们的自动旋转。- 你也可以通过对
willAnimateFirstHalfOfRotationToInterfaceOrientation:duration:
与willAnimateSencondHalfOfRotationToInterfaceOrientation:duration:
两个方法的重写来更加精细地配置我们的自动旋转视图。特别需要注意 的就是前一个方法在执行时,此时的UIInterfaceOrientation
仍然是旋转前的原有值,只有后一个方法在执行时UIInterfaceOrientation
才是屏幕旋转后的值。