iOS 6的Rotation 问题简述!

在ios5下画面的旋转都是shouldAutorotateToInterfaceOrientation来控制的,但是这个函数在ios6下不起作用。

在ios6下使用supportedInterfaceOrientations、shouldAutorotate来控制。


UIViewController的shouldAutorotateToInterfaceOrientation方法被deprecated。在ios6里,是使用supportedInterfaceOrientations and shouldAutorotate 2个方法来代替shouldAutorotateToInterfaceOrientation。注意:为了向后兼容iOS 4 and 5,还是需要在你的app里保留shouldAutorotateToInterfaceOrientation。



下面我们来看一些尝试:


for ios 4 and 5, 如果没有重写shouldAutorotateToInterfaceOrientation,那么对于iphone来讲,by default是只支持portrait,不能旋转。

for ios 6, 如果没有重写shouldAutorotate and supportedInterfaceOrientations,by default, iphone则是"可以旋转,支持非upside down的方向",而ipad是"可以选择,支持所有方向"


具体举例:

example 1: for ios 4 and 5, iphone device, 若要"可以旋转,支持非upside down的方向",则可以在view controller里

  1. - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {  
  2. return (interfaceOrientation != UIDeviceOrientationPortraitUpsideDown);  
  3. }  

example 2: for ios 6, iphone device, 若要“不能旋转,只支持portait",则可以在view controller里
  1. - (BOOL)shouldAutorotate  
  2. {  
  3.     return NO;  
  4. }  

example 3: for ios 6, ipad device, 若要“可以旋转,只支持landscape",则可以在view controller里
  1. -(NSUInteger)supportedInterfaceOrientations{  
  2.     return UIInterfaceOrientationMaskLandscape;  
  3. }  
  4.   
  5. - (BOOL)shouldAutorotate  
  6. {  
  7.     return YES;  
  8. }  


* 在iOS 4 and 5,都是由具体的view controller来决定对应的view的orientation设置。而在iOS 6,则是由top-most  controller来决定view的orientation设置。

举个例子:你的app的rootViewController是navigation controller "nav", 在”nav"里的stack依次是:main view -> sub view > sub sub view,而main view里有一个button会present modal view "modal view".

那么for ios 4 and 5,在ipad里,如果你要上述view都仅支持横屏orientation,你需要在上面的main view, sub view, sub sub view, model view里都添加

  1. - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {  
  2. return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation==UIInterfaceOrientationLandscapeRight);  
  3. }  

而对于iOS6, 由于是由top-most controller来设置orientation,因此你在main view, sub view, sub sub view里添加下面的代码是没有任何效果的,而应该是在nav controller里添加下列代码。而modal view则不是在nav container里,因此你也需要在modal view里也添加下列代码。
  1. -(NSUInteger)supportedInterfaceOrientations{  
  2.     return UIInterfaceOrientationMaskLandscape;  
  3. }  
  4.   
  5. - (BOOL)shouldAutorotate  
  6. {  
  7.     return YES;  
  8. }  

注意:

*你需要自定义一个UINavigationController的子类for "nav controller",这样才可以添加上述代码。

* 和navigation controller类似,tab controller里的各个view的orientation设置应该放在tab controller里


for ios6的top-most controller决定orientation设置,导致这样一个问题:在 top-most controller里的views无法拥有不相同的orientation设置。例如:for iphone, 在nav controller里,你有main view, sub view and sub sub view,前2个都只能打竖,而sub sub view是用来播放video,可以打横打竖。那么在ios 4 and 5里可以通过在main view and sub view的shouldAutorotateToInterfaceOrientation里设置只能打竖,而在sub sub view的shouldAutorotateToInterfaceOrientation设置打竖打横即可。而在ios 6里则无法实现这种效果,因为在main view, sub view and sub sub view的orientation设置是无效的,只能够在nav controller里设置。那么你可能想着用下列代码在nav controller里控制哪个view打竖,哪个view打横

  1. -(NSUInteger)supportedInterfaceOrientations{  
  2.     if([[self topViewController] isKindOfClass:[SubSubView class]])  
  3.         return UIInterfaceOrientationMaskAllButUpsideDown;  
  4.     else  
  5.         return UIInterfaceOrientationMaskPortrait;  
  6. }  

是的,这样可以使得在main view and sub view里无法打横,而sub sub view横竖都行。但问题来了,如果在sub sub view时打横,然后back to sub view,那么sub view是打横显示的!

目前想到的解决方法只能是把sub sub view脱离nav controller,以modal view方式来显示。这样就可以在modal view里设置打横打竖,而在nav controller里设置只打竖。


* 说了那么多,其实如果你的app的所有view的orientation的设置是统一的,那么你可以简单的在plist file里设置即可,不用添加上面的代码。而如果你添加了上面的代码,就会覆盖plist里orientation的设置。


* in iOS 6, 当view controller present时,不会call willRotateToInterfaceOrientation:duration:, willAnimateRotationToInterfaceOrientation:duration:, and didRotateFromInterfaceOrientation: methods,只有在发生rotate的时候才会call



综上所述:


如果单一的控制画面那么只需要加在上面两个函数。如下


[plain] view plain copy
  1. - (BOOL)shouldAutorotate {  
  2.   
  3.     return YES;  
  4. }  
  5.   
  6. - (NSUInteger)supportedInterfaceOrientations {  
  7.   
  8.     return UIInterfaceOrientationMaskAll;  
  9. }  
  1.   

如果是含有UINavigationController、UITabBarController的话,那么修改部分就多了。

用其派生类的,在派生类中增加上面的supportedInterfaceOrientations、shouldAutorotate函数。

下面如MyNavigationController就是UINavigationController   的派生类。修改部分如下

 1:在旧的程序中AppDelegate的部分如

定义的 UINavigationController            *navigationController;

[plain] view plain copy
  1. [window addSubview:[navigationController view]];  //不能旋转  

改为MyNavigationController            *myNavigationController;
  1. self.window.rootViewController = self.myNavigationController;  

派生类主要部分为

[plain] view plain copy
  1. #import "MyNavigationController.h"  
  2.   
  3. @interface MyNavigationController ()  
  4.   
  5. @end  
  6.   
  7. @implementation MyNavigationController  
  8.   
  9. - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil  
  10. {  
  11.     self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];  
  12.     if (self) {  
  13.         // Custom initialization  
  14.     }  
  15.     return self;  
  16. }  
  17.   
  18. - (void)viewDidLoad  
  19. {  
  20.     [super viewDidLoad];  
  21.     // Do any additional setup after loading the view.  
  22. }  
  23.   
  24. -(BOOL)shouldAutorotate  
  25. {  
  26.     return [self.viewControllers.lastObject shouldAutorotate];  
  27. }  
  28.   
  29. -(NSUInteger)supportedInterfaceOrientations  
  30. {  
  31.     return [self.viewControllers.lastObject supportedInterfaceOrientations];  
  32. }  
  33.   
  34. -(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation  
  35. {  
  36.     return [self.viewControllers.lastObject preferredInterfaceOrientationForPresentation];  
  37. }  
  38.   
  39. - (void)didReceiveMemoryWarning  
  40. {  
  41.     [super didReceiveMemoryWarning];  
  42.     // Dispose of any resources that can be recreated.  
  43. }  
  44.   
  45. @end  

这样就能控制所有的控制画面中的旋转了,当然别忘了在每个控制画面都增加旋转的函数。

根据多篇文章改写的,目前根据这样的方式,能够解决自己目前的问题,

如果大家还有更好的方式,还需要多指教。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值