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
相關文章
- [iOS]終極橫豎屏切換解決方案iOS
- Activity橫豎屏切換生命週期
- 40 橫豎屏切換略縮圖不能定位
- 直播電商平臺開發,橫豎屏切換的方法
- Swift橫豎屏切換、自動旋轉螢幕、手動旋轉螢幕、鎖定當前螢幕禁止轉屏、橫豎屏頁面跳轉過度、橫豎屏UI適配SwiftUI
- 投屏成功後,手機橫屏切豎屏小窗畫面向右偏移
- js監聽手機橫豎屏事件JS事件
- Android 橫豎屏處理的知識小結Android
- unity 動態修改當前橫豎屏狀態Unity
- Android 拍攝(橫 豎屏)視訊的懶人之路Android
- Android開發之平板和橫豎屏適配-RecyclerViewAndroidView
- 直播系統搭建,判斷螢幕橫豎屏狀態
- Flutter 特定頁面切換螢幕方向/iOS強制橫屏/SystemChrome.setPreferredOrientations不起作用 看這裡!FlutteriOSChrome
- 汽車之家原影片怎樣一鍵採集,批次橫屏改豎屏?
- T113啟動G2D旋轉豎屏當作橫屏使用
- 線上直播系統原始碼,強制應用全域性橫屏或豎屏原始碼
- 短視訊開發app,Android 強制應用全域性橫屏或豎屏APPAndroid
- iOS 切換鍵盤iOS
- 關於Android中使用BottomNavigationView切換橫屏導致返回主頁的問題AndroidNavigationView
- 短視訊app開發,視訊、直播畫面跟隨手機橫屏、豎屏移動APP
- 是豎屏簡易操作還是橫屏精細玩法?休閒手遊的近期走向觀察
- 不想橫屏看視訊?谷歌開源框架AutoFlip一鍵截出最精彩豎版視訊谷歌框架
- PR模板-200個橫屏豎屏摺疊翻頁拉伸透視運動毛刺膠片煙霧影片轉場預設
- 滑鼠懸浮中英文切換橫向導航選單
- 簡單實現一個全面屏切換效果
- 線上文字豎排排版工具--將橫版內容轉換為豎版,同時支援繁體和間隔符的自定義
- iOS學習筆記04 檢視切換iOS筆記
- Win10如何將音量條從橫向變為豎向 win10音量條怎麼從橫向變為豎向Win10
- 仿Word的支援橫軸豎軸的WPF 標尺
- 小程式類似抖音視訊整屏切換
- iOS開發之APP內部切換語言iOSAPP
- 替換橫槓
- echarts折線圖使用dataZoom,切換資料時渲染異常,出現豎線bugEchartsOOM
- 如何去掉bootstrap table中表格樣式中橫線豎線boot
- 電腦螢幕橫過來了怎麼恢復 電腦螢幕橫屏了怎麼轉換
- H5單頁面手勢滑屏切換原理H5
- 騰訊會議橫屏如何設定?騰訊會議橫屏設定方法
- 處理短屏下縮放,以及初始化時固定頁面大小,防止豎屏下彈出鍵盤或橫屏時頁面發生縮放的情況
- uniapp 小程式橫屏的方式APP