標籤:
藉助通知來控制介面的橫豎屏切換。
還是整個App中大部分介面都是豎屏,某個介面可以橫豎屏切換的情況。
首先,在【General】-->【Device Orientation】設定僅支援豎屏,like this:
Device Orientation
然後在特殊的視圖控制器裡的ViewDidLoad中註冊通知:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceOrientationDidChange) name:UIDeviceOrientationDidChangeNotification object:nil];
通知方法的實現過程:
- (void)deviceOrientationDidChange{ NSLog(@"deviceOrientationDidChange:%ld",(long)[UIDevice currentDevice].orientation); if([UIDevice currentDevice].orientation == UIDeviceOrientationPortrait) { [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait]; [self orientationChange:NO]; //注意: UIDeviceOrientationLandscapeLeft 與 UIInterfaceOrientationLandscapeRight } else if ([UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeLeft) { [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight]; [self orientationChange:YES]; }}- (void)orientationChange:(BOOL)landscapeRight{ if (landscapeRight) { [UIView animateWithDuration:0.2f animations:^{ self.view.transform = CGAffineTransformMakeRotation(M_PI_2); self.view.bounds = CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); }]; } else { [UIView animateWithDuration:0.2f animations:^{ self.view.transform = CGAffineTransformMakeRotation(0); self.view.bounds = CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); }]; }}// 用到的兩個宏: #define SCREEN_WIDTH ([UIScreen mainScreen].bounds.size.width) #define SCREEN_HEIGHT ([UIScreen mainScreen].bounds.size.height)
最重要的一點:
需要重寫如下方法,並且返回NO。
- (BOOL)shouldAutorotate{ return NO;}
這樣,在裝置出於橫屏時,介面就會變成橫屏,裝置處於豎屏時,介面就會變成豎屏。
填坑
// UINavigationController:- (BOOL)shouldAutorotate{ return [self.topViewController shouldAutorotate];}- (UIInterfaceOrientationMask)supportedInterfaceOrientations{ return [self.topViewController supportedInterfaceOrientations];}// UITabBarController:- (BOOL)shouldAutorotate{ return [self.selectedViewController shouldAutorotate];}- (UIInterfaceOrientationMask)supportedInterfaceOrientations{ return [self.selectedViewController supportedInterfaceOrientations];}
// 橫屏- (IBAction)landscapAction:(id)sender { [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight]; [self orientationChange:YES];}
但是按照上面的寫法,會導致返回到之前的介面時,視圖方向錯誤,即使返回前執行如下代碼:
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];[self orientationChange:NO];
也沒有作用,下面是在開源工程中無意看到的寫法:
// 橫屏- (IBAction)landscapAction:(id)sender { [self interfaceOrientation:UIInterfaceOrientationLandscapeRight];}// 豎屏- (IBAction)portraitAction:(id)sender { [self interfaceOrientation:UIInterfaceOrientationPortrait];}- (void)interfaceOrientation:(UIInterfaceOrientation)orientation{ if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]) { SEL selector = NSSelectorFromString(@"setOrientation:"); NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[UIDevice instanceMethodSignatureForSelector:selector]]; [invocation setSelector:selector]; [invocation setTarget:[UIDevice currentDevice]]; int val = orientation; [invocation setArgument:&val atIndex:2]; [invocation invoke]; }}
上面的方法會將裝置的方向強制設定為某個方向,然後再監控裝置方向改變的通知,即可實現橫豎屏切換。
這裡有一個用JS 和原生item 控制橫豎屏切換的Demo。地址
這是:
iOS代碼處理橫屏問題