iOS6对于shouldAutorotateToInterfaceOrientation的改动以及其他一些窗口相关细节

iOS6正式版发布当天博主我就更新了,随后也更新了对应的XCode以及iOS SDK,更新到了4.5 (4G182)。然后更新原有4.4 iOS5 SDK的项目,目前最主要的发现就是iOS6对于app屏幕朝向支持以及自动旋屏时的处理方式的变动。

简而言之就是iOS6下的

1 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
2 {
3     return UIInterfaceOrientationIsLandscape(toInterfaceOrientation);
4 }

这个不会再被调用,取而代之的是这俩个组合:

1 - (BOOL)shouldAutorotate
2 {
3     return YES;
4 }
5  
6 - (NSUInteger)supportedInterfaceOrientations
7 {
8     return UIInterfaceOrientationMaskLandscape;
9 }

当然,为了保持对旧版本系统行为的兼容性,不要删掉不用的那个调用。另外还有一个这个preferred朝向也可以加上

1 - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
2 {
3     return UIInterfaceOrientationLandscapeRight;
4 }

当我替换完这俩个操作后尝试运行app,发现会报如下的异常:
Terminating app due to uncaught exception ‘UIApplicationInvalidInterfaceOrientation’, reason: ‘Supported orientations has no common orientation with the application, and shouldAutorotate is returning YES’

经查发现导致此异常的原因是app再info.plist中指定的屏幕朝向没有portrait,也就是只支持landscape横屏,但是app集成了Game Center应用,而Game Center触发的登录界面只支持竖屏显示(这点有开发帐号的朋友可以到苹果官方开发论坛上看下,有个苹果官方人员发的证实贴,由于现阶段的NDA就不转了),解决这个问题的方法就是再应用的delegate中加入如下回调:

1 - (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
2 {
3     if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
4         return UIInterfaceOrientationMaskAll;
5     else  /* iphone */
6         return UIInterfaceOrientationMaskAllButUpsideDown;
7 }

这样就可以再不改变info.plist中的设置的前提下,兼容gamecenter的竖屏登录问题。
顺带一提,对于Game Center排行等界面的旋屏朝向限制方法:

1 @implementation GKLeaderboardViewController(Landscape)
2  
3 - (BOOL)shouldAutorotate
4 {
5     return YES;
6 }
7  
8 - (NSUInteger)supportedInterfaceOrientations
9 {
10     returnUIInterfaceOrientationMaskLandscapeRight|UIInterfaceOrientationMaskLandscapeLeft;
11 }
12  
13 - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
14 {
15     return UIInterfaceOrientationLandscapeRight;
16 }
17  
18 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
19 {
20     return UIInterfaceOrientationIsLandscape(interfaceOrientation);
21 }
22  
23 @end

这个时候确实感到objective-c的category之方便啊,呵呵。

再有一个问题就是window的rootViewController问题,在iOS6下,必须通过setRootViewController指定根视图控制器,否则didFinishLaunchingWithOptions结束后会报必须指定根视图控制器的错误。网上看到有人提到在iOS6下addSubview的方法将不再起作用,而必须使用指定rootViewController的方式,而我实际测试时还发现了另外一个小问题,就是在切换view的时候,比如用MPMoviePlayerViewController播放intro视频,然后再切换到游戏OpenGL视图时的addSubView和removeFromSuperview的交替会出现一些奇怪的GL视图朝向错误问题,而且也找不到任何相关旋屏的log输出,最后发现只要是用了iOS6的SDK就必须调用setRootViewController,iOS6以前的系统还需要额外调用addSubview,这样就不会出现那种切换view后的诡异问题了,至少我目前找到的解决方法是这样,不知是否另有玄机?附上改后的根据系统版本号执行不同切换方式的简单代码:

1 if ([[UIDevice currentDevice].systemVersion floatValue]<6.0)
2 {
3     // 高兼容性的做法
4     [self.window setRootViewController:self.viewController];
5     [self.window addSubview:self.viewController.view];
6 }
7 else
8 {
9     [self.window setRootViewController:self.viewController];
10 }
11 [self.viewController.view setNeedsDisplay];

最后再爆料一个屏幕初始朝向的问题,我们知道,设定屏幕初始朝向的方法是再info.plist中指定Initial interface orientation项,而我发现无论怎么设置,横屏都只能以landscape-left的方式启动,就是按钮在左边那种,不管是升级的旧项目,还是新建的项目均是如此,不知是否有朋友也遇到了这个问题?



子类化
@implementation UINavigationController (Rotation_IOS6)

-(BOOL)shouldAutorotate
{
    return [[self.viewControllers lastObject] shouldAutorotate];
}

-(NSUInteger)supportedInterfaceOrientations
{
    return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}

@end

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值