iOS_控制螢幕旋轉
技術標籤:iOS
1 首先在Xcode工程配置中設定 專案支援哪些方向上的旋轉
從上往下分別是 上、下、左右 如圖所示 表示當前專案 支援豎屏、左右橫屏。Xcode中的配置是全域性的,意味著專案中所有的控制器都預設支援這些方向的旋轉。
2 控制器單獨控制
Xcode工程配置中設定了全域性支援的旋轉方向,不過實際專案中經常不是所有的控制器都支援一樣的旋轉方向,所以需要通過程式碼實現控制器的單獨配置。
為了能看懂程式碼 這裡先介紹下跟旋轉有關的三個列舉
UIDeviceOrientation: 裝置旋轉方向
typedef NS_ENUM(NSInteger, UIDeviceOrientation) { 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 } API_UNAVAILABLE(tvos);
UIInterfaceOrientation:螢幕旋轉方向
typedef NS_ENUM(NSInteger, UIInterfaceOrientation) { UIInterfaceOrientationUnknown = UIDeviceOrientationUnknown, UIInterfaceOrientationPortrait = UIDeviceOrientationPortrait, UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown, UIInterfaceOrientationLandscapeLeft = UIDeviceOrientationLandscapeRight, UIInterfaceOrientationLandscapeRight = UIDeviceOrientationLandscapeLeft } API_UNAVAILABLE(tvos);
UIInterfaceOrientationMask:看程式碼的定義 可以理解為 用於對UIInterfaceOrientation的描述
typedef NS_OPTIONS(NSUInteger, UIInterfaceOrientationMask) { UIInterfaceOrientationMaskPortrait = (1 << UIInterfaceOrientationPortrait), UIInterfaceOrientationMaskLandscapeLeft = (1 << UIInterfaceOrientationLandscapeLeft), UIInterfaceOrientationMaskLandscapeRight = (1 << UIInterfaceOrientationLandscapeRight), UIInterfaceOrientationMaskPortraitUpsideDown = (1 << UIInterfaceOrientationPortraitUpsideDown), UIInterfaceOrientationMaskLandscape = (UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight), UIInterfaceOrientationMaskAll = (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskPortraitUpsideDown), UIInterfaceOrientationMaskAllButUpsideDown = (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight), } API_UNAVAILABLE(tvos);
然後通過檢視官方API可以看到UIViewController中聲明瞭以下三個屬性
// 是否支援螢幕旋轉 當這個值為NO時 當前控制器只能豎屏
@property(nonatomic, readonly) BOOL shouldAutorotate ;
// 當前控制器支援的旋轉方向
@property(nonatomic, readonly) UIInterfaceOrientationMask supportedInterfaceOrientations;
// 頁面出現時的預設旋轉方向
@property(nonatomic, readonly) UIInterfaceOrientation preferredInterfaceOrientationForPresentation;
這三個屬性是隻讀的,所以沒法用set方法去設定,不過可以通過重寫get方法的形勢來返回想要的值 比如以下程式碼所示
// 返回yes表示支援旋轉
- (BOOL)shouldAutorotate
{
return YES;
}
// 支援豎屏和橫屏
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscape);
}
// 預設旋轉左邊
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationLandscapeLeft;
}
不過要注意的是 如果當前控制器是屬於一個導航控制器的 那麼導航控制器中要實現
// 是否支援自動旋轉螢幕
- (BOOL)shouldAutorotate {
return self.topViewController.shouldAutorotate;
}
// 支援哪些螢幕方向
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return self.topViewController.supportedInterfaceOrientations;
}
// 預設的螢幕方向(當前ViewController必須是通過模態出來的UIViewController(模態帶導航的無效)方式展現出來的,才會呼叫這個方法)
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return self.topViewController.preferredInterfaceOrientationForPresentation;
}
同樣的 如果控制器外面還有一層TabBarViewControllre那麼 TabBarViewControllre要實現
// 是否支援自動旋轉螢幕
- (BOOL)shouldAutorotate {
return self.selectedViewController.shouldAutorotate;
}
// 支援哪些螢幕方向
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return self.selectedViewController.supportedInterfaceOrientations;
}
// 預設的螢幕方向(當前ViewController必須是通過模態出來的UIViewController(模態帶導航的無效)方式展現出來的,才會呼叫這個方法)
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return self.selectedViewController.preferredInterfaceOrientationForPresentation;
}
到了這裡 我們就知道了 怎麼全域性或單獨配置某個ViewController是否支援、支援哪些方向的旋轉。當手機裝置旋轉時,介面也會相應的旋轉。
3 監聽螢幕的旋轉
既然某個VC支援了螢幕旋轉,也就意味著 該介面的豎屏和橫屏是兩套不同的UI,所以當螢幕旋轉時,監聽系統發出的通知,及時重新整理UI 做好橫豎屏的適配。
// 監聽螢幕旋轉
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationDidChange) name:UIDeviceOrientationDidChangeNotification object:nil];
- (void)orientationDidChange
{
switch ([UIDevice currentDevice].orientation) {
case UIDeviceOrientationPortrait:
self.isFullScreen = NO;
break;
case UIDeviceOrientationLandscapeLeft:
self.isFullScreen = YES;
break;
case UIDeviceOrientationLandscapeRight:
self.isFullScreen = YES;
break;
default:
break;
}
}
4 主動控制螢幕的旋轉
當鎖定了iPhone的方向之後,旋轉手機,UIDevice的orientation屬性不會改變,同時系統也不會發出UIDeviceOrientationDidChangeNotification通知,此時我們只能通過程式碼的方式強制修改當前Device的orientation,當orientation改變時,系統會發出UIDeviceOrientationDidChangeNotification通知
// 因為orientation屬性是隻讀的 所有這裡通過KVC的形式來設定值
[[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:orientation]
forKey:@"orientation"];