【Swift4】一部の画面(ViewController)だけ画面を回転させる方法【Objective-C】

2020年8月27日

一部の画面(ViewController)のみ横向きなどの回転を実装する方法です。

1.事前準備

TARGET > General > Deployment Info > Device Orientation
全ての方向の回転を許可しておきます。

2.ViewController内でshouldAutorotateを実装する

ViewControllerに- (BOOL)shouldAutorotateメソッドを実装し、YES・NOで回転の許可、不許可をView

2-1. 回転したいViewControllerはYES

Swift4

override var shouldAutorotate: Bool {
    get {
        return true
    }
}
override func willAnimateRotation(to toInterfaceOrientation: UIInterfaceOrientation, duration: TimeInterval) {
    if(interfaceOrientation == .portrait){
        // 縦(ホームボタンが下)
    }
    else if(interfaceOrientation == .portraitUpsideDown){
        // 縦(ホームボタンが上)
    }
    else if(interfaceOrientation == .landscapeLeft){
        // 横(ホームボタンが左)
    }
    else if(interfaceOrientation == .landscapeRight){
        // 横(ホームボタン右)
    }
}

Objective-C

- (BOOL)shouldAutorotate {
    return YES;
}
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration {
    if(interfaceOrientation == UIInterfaceOrientationPortrait){
        // 縦(ホームボタンが下)
    }
    else if(interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown){
        // 縦(ホームボタンが上)
    }
    else if(interfaceOrientation == UIInterfaceOrientationLandscapeLeft){
        // 横(ホームボタンが左)
    }
    else if(interfaceOrientation == UIInterfaceOrientationLandscapeRight){
        // 横(ホームボタン右)
    }
}

回転したことを受け取るメソッドも実装

2-2. 回転したくないViewControllerはNO

Swift4

override var shouldAutorotate: Bool {
    get {
        return false
    }
}

Objective-C

- (BOOL)shouldAutorotate {
    return NO;
}

3. NavigationController内のViewControllerの場合

ナビゲーションコントローラー内にあるViewControllerの場合、ナビゲーションコントローラー自体を回転させる必要があるため、ViewControllerで個別にshouldAutorotateを実装しても、回転することはありません。

そこで、ViewControllerで個別に実装したshouldAutorotateの結果をナビゲーションコントローラーに適応させる実装が必要になります。

Swift4

import UIKit

extension UINavigationController {
    open override var shouldAutorotate: Bool {
        guard let viewController = self.visibleViewController else { return true }
        return viewController.shouldAutorotate
    }
    
    override open func willAnimateRotation(to toInterfaceOrientation: UIInterfaceOrientation, duration: TimeInterval) {
        let viewController = self.visibleViewController
        viewController?.willAnimateRotation(to: toInterfaceOrientation, duration: duration)
    }
}

Extension.swiftを作成します。

Objective-C

#import <UIKit/UIKit.h>

@interface UINavigationController (Helper)

@end

UINavigationController+Helper.hを作成します。

#import "UINavigationController+Helper.h"

@implementation UINavigationController (Helper)

- (BOOL)shouldAutorotate {
    return [self.viewControllers.lastObject shouldAutorotate];
}

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration {
    [self.viewControllers.lastObject willAnimateRotationToInterfaceOrientation:interfaceOrientation duration:duration];
}

@end

UINavigationController+Helper.mを作成します。

#import "UINavigationController+Helper.h"

あとはナビゲーションコントローラー内に入るViewControllerで作成したhファイルをインポートします。

これで、ナビゲーションコントローラーに現在表示しているViewControllerのshouldAutorotateの設定を適応することができます。