iOS 橫豎屏切換
一、基本說明
UIDeviceOrientation 是機器硬體的當前旋轉方向 這個你只能取值 不能設定
UIInterfaceOrientation 是你程式介面的當前旋轉方向 這個可以設定
Portrait 表示 縱向,Landscape 表示 橫向。
- typedef enum {
- UIDeviceOrientationUnknown,
- UIDeviceOrientationPortrait, // Device oriented vertically, home button on the bottom
- UIDeviceOrientationPortraitUpsideDown, // Device oriented vertically, home button on the top
- UIDeviceOrientationLandscapeLeft, // Device oriented horizontally, home button on the right
- UIDeviceOrientationLandscapeRight, // Device oriented horizontally, home button on the left
- UIDeviceOrientationFaceUp, // Device oriented flat, face up
- UIDeviceOrientationFaceDown // Device oriented flat, face down
- } UIDeviceOrientation;
- typedef enum {
- UIInterfaceOrientationPortrait = UIDeviceOrientationPortrait,
- UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown,
- UIInterfaceOrientationLandscapeLeft = UIDeviceOrientationLandscapeRight,
- UIInterfaceOrientationLandscapeRight = UIDeviceOrientationLandscapeLeft
-
//注意Interface和Device的左右是相反的
- } UIInterfaceOrientation;
- #define UIDeviceOrientationIsPortrait(orientation) ((orientation) == UIDeviceOrientationPortrait || (orientation) == UIDeviceOrientationPortraitUpsideDown)
- #define UIDeviceOrientationIsLandscape(orientation) ((orientation) == UIDeviceOrientationLandscapeLeft || (orientation) == UIDeviceOrientationLandscapeRight)
判斷裝置現在的方向:
- - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
- {
- //宣告一個UIDevice指標,並取得目前Device的狀況
- UIDevice *device = [UIDevice currentDevice] ;
- //取得當前Device的方向,來當作判斷敘述。(Device的方向型態為Integer)
- switch (device.orientation) {
- case UIDeviceOrientationFaceUp:
- NSLog(@"螢幕朝上平躺");
- break;
- case UIDeviceOrientationFaceDown:
- NSLog(@"螢幕朝下平躺");
- break;
- //系統無法判斷目前Device的方向,有可能是斜置
- case UIDeviceOrientationUnknown:
- NSLog(@"未知方向");
- break;
- case UIDeviceOrientationLandscapeLeft:
- NSLog(@"螢幕向左橫置");
- break;
- case UIDeviceOrientationLandscapeRight:
- NSLog(@"螢幕向右橫置");
- break;
- case UIDeviceOrientationPortrait:
- NSLog(@"螢幕直立");
- break;
- case UIDeviceOrientationPortraitUpsideDown:
- NSLog(@"螢幕直立,上下顛倒");
- break;
- default:
- NSLog(@"無法辨識");
- break;
- }
- // Return YES for supported orientations
- return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft); // 只支援向左橫向, YES 表示支援所有方向
- }
或者
- - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
- {
- UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
- if (UIDeviceOrientationIsLandscape(deviceOrientation)) NSLog(@"橫向");
- else if(UIDeviceOrientationIsPortrait(deviceOrientation)) NSLog(@"縱向");
- // // Return YES for supported orientations
- return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft); // 只支援向左橫向, YES 表示支援所有方向
- }
二、使用場景
1、一般情形,所有介面都支援橫豎屏切換
如果App的所有切面都要支援橫豎屏的切換,那隻需要勾選【General】 中的【Device Orientation】,選擇希望支援的方向即可。
如上設定完之後,當裝置豎屏的時候,所有的介面都是豎屏顯示的;而當裝置橫屏Home在右側時,所有的介面會橫屏顯示。其他方向不支援,介面不會改變。
這裡有個坑:
在iOS 9 之後橫屏時,狀態列會消失。
解決方法:確保plist 中的【View controller-based status bar appearance】為YES,然後重寫ViewController的 - (BOOL)prefersStatusBarHidden
,返回值是NO。
- (BOOL)prefersStatusBarHidden { return NO; }2、特殊情形,個別介面固定方向,其他所有介面都支援橫豎屏切換
這種情況,在【General】-->【Device Orientation】中設定好支援的方向後,只需要在這些特殊的固定方向的檢視控制器中重寫兩個方法:
// 支援裝置自動旋轉 - (BOOL)shouldAutorotate { return YES; } /** * 設定特殊的介面支援的方向,這裡特殊介面只支援Home在左側的情況 */ - (UIInterfaceOrientationMask)supportedInterfaceOrientations { return UIInterfaceOrientationMaskLandscapeRight; }
3、特殊情形:個別介面支援橫豎屏切換,其他所有介面都固定方向
可能大多數App會是這種需求,某些特殊介面只能橫屏,如視訊播放類App。 這裡有兩種處理方式: 方式一 在【General】-->【Device Orientation】中設定好需要支援的所有方向。然後使用一個基類控制器,在基類控制器中重寫兩個控制橫豎屏的方法:
// 支援裝置自動旋轉 - (BOOL)shouldAutorotate { return YES; } // 支援豎屏顯示 - (UIInterfaceOrientationMask)supportedInterfaceOrientations { return UIInterfaceOrientationMaskPortrait; }
再然後,特殊的介面上再重寫這倆方法,讓其可以自動切換方向。
// 如果需要橫屏的時候,一定要重寫這個方法並返回NO
- (BOOL)prefersStatusBarHidden { return NO; } // 支援裝置自動旋轉 - (BOOL)shouldAutorotate { return YES; } // 支援橫屏顯示 - (UIInterfaceOrientationMask)supportedInterfaceOrientations { // 如果該介面需要支援橫豎屏切換 return UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskPortrait; // 如果該介面僅支援橫屏 // return UIInterfaceOrientationMaskLandscapeRight; }
方式二
用方式一的方法,還需要藉助一個基類,所有的控制器都要繼承這個基類,太麻煩?
另一種方式,是藉助通知來控制介面的橫豎屏切換。
還是整個App中大部分介面都是豎屏,某個介面可以橫豎屏切換的情況。
首先,在【General】-->【Device Orientation】設定僅支援豎屏,like this:
然後在特殊的檢視控制器裡的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; }這樣,在裝置出於橫屏時,介面就會變成橫屏,裝置處於豎屏時,介面就會變成豎屏。
填坑
上面方式二,因為【General】-->【Device Orientation】因為只設定了豎屏,所以當橫屏時,如果有鍵盤彈出,鍵盤是豎屏時的樣式。
解決辦法:在【General】-->【Device Orientation】中加上橫屏時的方向。如果VieController 是放在UINavigationController或者UITabBarController中,需要重寫它們的方向控制方法。
// 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]; } }
上面的方法會將裝置的方向強制設定為某個方向,然後再監控裝置方向改變的通知,即可實現橫豎屏切換。
參考:http://justcoding.iteye.com/blog/1472932
http://www.cocoachina.com/ios/20160722/17148.html
相關文章
- Android橫豎屏切換Android
- [iOS]終極橫豎屏切換解決方案iOS
- Activity橫豎屏切換生命週期
- iOS橫豎屏iOS
- [貝聊科技] iOS 終極橫豎屏切換解決方案iOS
- 橫屏和豎屏切換介面不重新整理
- 40 橫豎屏切換略縮圖不能定位
- 直播電商平臺開發,橫豎屏切換的方法
- dialog橫豎屏切換時消失的解決方法
- Android在橫豎屏切換時到底發生了什麼?Android
- 橫豎屏切換中的介面設計與體驗提升
- iOS 橫豎屏旋轉總結iOS
- activity橫屏豎屏
- 你還在問android橫豎屏切換的生命週期?Android
- Swift橫豎屏切換、自動旋轉螢幕、手動旋轉螢幕、鎖定當前螢幕禁止轉屏、橫豎屏頁面跳轉過度、橫豎屏UI適配SwiftUI
- Android系統橫豎屏切換時候Activity的生命週期Android
- 投屏成功後,手機橫屏切豎屏小窗畫面向右偏移
- 程式碼處理 iOS 的橫豎屏旋轉iOS
- 檢測橫屏豎屏程式碼
- android轉屏,切換螢幕,橫豎屏(onConfigurationChanged)會重新 OnCreate 的解決方案Android
- perl橫豎轉換
- App中橫豎屏的設定APP
- 匹配橫屏或者豎屏css程式碼例項CSS
- js監聽手機橫豎屏事件JS事件
- ios橫屏設定iOS
- 4、[ iOS ] 禁止橫屏iOS
- unity 動態修改當前橫豎屏狀態Unity
- Android 橫豎屏處理的知識小結Android
- Android 拍攝(橫 豎屏)視訊的懶人之路Android
- 直播系統搭建,判斷螢幕橫豎屏狀態
- Android 拍攝(橫 \ 豎屏)視訊的懶人之路Android
- 關於iPad應用強制橫豎屏問題iPad
- 純CSS(media queries)實現移動端橫豎屏提示CSS
- Android開發之平板和橫豎屏適配-RecyclerViewAndroidView
- 線上直播系統原始碼,強制應用全域性橫屏或豎屏原始碼
- iOS使用Autolayout-SizeClass解決橫豎屏控制元件位置差別較大情況iOS控制元件
- Flutter 特定頁面切換螢幕方向/iOS強制橫屏/SystemChrome.setPreferredOrientations不起作用 看這裡!FlutteriOSChrome
- 短視訊開發app,Android 強制應用全域性橫屏或豎屏APPAndroid