iOS 화면 회전 처리
최근 프로젝트 도중 화면 회전에 관련된 코드를 사용해 보았다. 비교적 간단한 내용이지만 나에게 다시 상기시키고자 정리해본다.
프로젝트 앱은 기본적으로 아이폰의 세로모드만 지원했지만 영상을 관리하는 뷰 컨트롤러를 새로 만들면서 비디오가 재생되는 곳은 가로모드를 지원하게 하고 싶었다.
전체적인 방향 설정
먼저 앱의 전체적인 방향 설정부터 알아보자.
Supported interface orientations
앱은 기본적으로 Info.plist
의 Supported interface orientations
를 참조한다. 다음 그림은 프로젝트 생성 후 Info.plist
의 Supported interface orientations
키의 디폴트 값을 보여준다.
정리해보면,
- iPhone
- Portrait: bottom home button
- Landscape: left home button
- Landscape: right home button
iPad
- Portrait: bottom home button
- Landscape: left home button
- Landscape: right home button
- Portrait: top home button)
Info.plist
에서 이 값들을 지우거나 더함으로써 앱의 기본적인 방향을 정해줄 수 있다.
supportedInterfaceOrientations(for:)
두번째는 AppDelegate
의 application(_:supportedInterfaceOrientationsFor:)
함수를 사용하는 것이다.
1 | func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) |
앱이 지원하는 방향을 설정할 수 있으며 옵셔널
한 메소드이기 때문에 구현을 하지 않을시 Info.plist
의 지원 방향을 참조한다. 이 메소드는 OptionSet을 준수하는 UIInterfaceOrientationMask
구조체를 리턴하며 iOS 기기의 모든 방향이 정리되어 있다.
공식 문서에는 이 메소드에 대해 이렇게 나와 있다.
When determining whether to rotate a particular view controller, the orientations returned by this method are intersected with the orientations supported by the root view controller or topmost presented view controller. The app and view controller must agree before the rotation is allowed.
즉, 어떤 뷰 컨트롤러를 돌리는 것을 결정할 때 이 메소드에서 지원하는 방향이 그 뷰가 돌리려는 방향을 지원하지 않으면 돌릴 수 없다는 말이다. 이 메소드가 앱의 가장 상위에서 방향을 제어하고 있다고 볼 수 있다. 이것은 특정 뷰 컨트롤러의 방향을 설정할 때 중요한데 예를 들어 전체적인 앱의 방향은 세로로 고정되어 있는데 특정 뷰 컨트롤러는 가로 모드도 지원을 하고 싶다면 이 AppDelegate
메소드에서 가로 모드를 명시해줘야 한다는 뜻이다.
View Controller의 방향 설정
다음은 개별 ViewController의 방향 설정이다.
shouldAutorotate
먼저 shouldAutorotate
프로퍼티를 보자.
1 | var shouldAutorotate: Bool { get } |
뷰 컨트롤러가 돌아가는 것을 결정하는 Bool
타입의 뷰 컨트롤러 인스턴스 프로퍼티이다. 뷰 컨트롤러 내에서 self
로 접근하면 읽는 것만 가능하지만 상위 클래스인 UIViewController
의 프로퍼티를 오버라이드하여 수정할 수 있다.
supportedInterfaceOrientations
그 다음으로 supportedInterfaceOrientations
프로퍼티를 보자.
1 | var supportedInterfaceOrientations: UIInterfaceOrientationMask { get } |
뷰 컨트롤러가 지원하는 방향을 가리키는 인스턴스 프로퍼티로 역시 오버라이드하여 변경 가능하다. 이 메소드는 shouldAutorotate
메소드가 true
값을 반환할 때만 불리게 되며 이 메소드에서 지원하는 방향이 위에서 말한 앱 전체적 지원 방향에 들어가 있다면 그 방향으로 회전하는 것이 가능하다.
이 두가지 메소드를 통해 뷰 컨트롤러의 회전을 제어할 수 있다. 여기서 중요한 것은 만약 뷰 컨트롤러의 상위 뷰 컨트롤러가 있다면 그 뷰 컨트롤러의 두 메소드를 따른다는 것이다. 예를 들어 UINavigationController가 Portrait 모드만 지원한다면 그 안에 있는 ViewController에서 Landscape를 지원한다고 명시해도 지원할 수 없다.
추가적으로 화면을 뷰가 전환되거나 할 때 강제로 뷰의 방향을 바꾸고 싶다면 currentDevice의 key-value로 접근하여 바꿀 수 있다.
1 | let orientationValue = UIInterfaceOrientationMask.landscapeLeft.rawValue |