1. 程式人生 > 其它 >iOS_控制螢幕旋轉

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"];