ios6,7适配旋转

知识点:

*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里

[cpp]  view plain copy
  1. - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {  
  2. return (interfaceOrientation != UIDeviceOrientationPortraitUpsideDown);  
  3. }  

example 2: for ios 6, iphone device, 若要“不能旋转,只支持portait",则可以在view controller里

[cpp]  view plain copy
  1. - (BOOL)shouldAutorotate  
  2. {  
  3.     return NO;  
  4. }  

example 3: for ios 6, ipad device, 若要“可以旋转,只支持landscape",则可以在view controller里

[cpp]  view plain copy
  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里都添加

[cpp]  view plain copy
  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里也添加下列代码。

[cpp]  view plain copy
  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打横

[cpp]  view plain copy
  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


//////

//////

stackOverflow..

I have an iPhone app I am updating to iOS 6 that is having rotation issues. I have aUITabBarController with 16 UINavigationCotrollers. Most of the subviews can work in portrait or landscape but some of them are portrait only. With iOS 6 things are rotating when they shouldn't.

I tried subclassing the tabBarController to return the supportedInterfaceOrienations of the current navigationController's selected viewController:

- (NSUInteger)supportedInterfaceOrientations{

UINavigationController *navController = (UINavigationController *)self.selectedViewController;

return [navController.visibleViewController supportedInterfaceOrientations];

}

This got me closer. The view controller won't rotate out of position when visible, but if I am in landscape and switch tabs the new tab will be in landscape even if it isn't supported.

Ideally the app will only be in the supported orienation of the current visible view controller. Any ideas?


answer:

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

Subclass your UITabBarController overriding these methods:

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // You do not need this method if you are not supporting earlier iOS Versions
    return [self.selectedViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation];
}

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

-(BOOL)shouldAutorotate
{
    return YES;
}

Subclass your UINavigationController overriding these methods:

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

-(BOOL)shouldAutorotate
{
    return YES;
}

Then implement these methods in your viewControllers that you do not want to rotate:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

-(BOOL)shouldAutorotate
{
    return NO;
}

-(NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;
}

And for viewControllers that you do want to rotate:

    - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
    {
        return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
    }

    -(NSUInteger)supportedInterfaceOrientations
    {
        return UIInterfaceOrientationMaskAllButUpsideDown;
    }

    -(BOOL)shouldAutorotate
    {
        return YES;
    }

Your tabbarController should be added as the RootviewController of the app window. If you plan to support the default orientations, all but upsidedown is default for iPhone, then you do not need to do anything else. If you want to support upside-down or if you do not want to support another of the orientations, then you need to set the appropriate values in app delegate and/or info.plist.


链接:

http://stackoverflow.com/questions/12504464/ios-6-uitabbarcontroller-supported-orientation-with-current-uinavigation-control


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值