iOS ) UITraitEnvironment와 traitCollectionDidChange
안녕하세요 :) Zedd입니다.
오늘은 UITraitEnvironment와 traitCollectionDidChange를 알아봅시다!
# traitCollectionDidChange은 어디에?
traitCollectionDidChange는 인스턴스 메소드입니다.
그럼 어느 타입안에 들어있는 메소드일까요?
traitCollectionDidChange은 UITraitEnvironment이라는 프로토콜안에 있는 메소드입니다.
UIViewController, UIView가 이를 conform하고 있기때문에,
우리는 UIViewController나 UIView에서
traitCollectionDidChange를 오버라이드할 수 있게 됩니다.
(UIViewController, UIView이외에도 UIScreen, UIWindow, UIPresentationController가 이를 채택합니다.)
# UITraitEnvironment
그럼 UITraitEnvironment을 먼저 공부해보는게 좋을 것 같습니다.
iOS interface environment에는
- horizontal / vertical size class
- display scale
- user interface idiom
- user interface style
같은 trait이 포함된다고 합니다.
이 UITraitEnvironment프로토콜을 채택하는 객체의 trait environment에 접근하려면
UITraitEnvironment에 있는 traitCollection이라는 프로퍼티를 사용하면 됩니다.
# traitCollection
iOS interface environment에는
- horizontal / vertical size class
- display scale
- user interface idiom
- userInterfaceStyle
이런것들이 있고, 여기에 접근하려면 traitCollection프로퍼티를 사용하면 된다고 그랬습니다.
(위에 나열한 것들만 있는것이 아니라 엄청 많습니다. 자세한 사항은 문서를 참고해주세요)
display scale부터 보도록 하겠습니다.
- display scale
self.traitCollection.displayScale
아이폰 12 프로 Max는 3x 디바이스니 3.0이 나오고
아이폰 SE 2세대는 2x 디바이스니 2.0이 나오게 됩니다.
- user interface idiom
self.traitCollection.userInterfaceIdiom
현재 내 UI에 맞는 idom이 나오게 됩니다.
- user Interface Style
light / dark중 어떤 환경인지 알려주는 값입니다.
- horizontal / vertical size class
디바이스의 portrait, landscape에 따라 현재 화면의 size class가 Compact / Regular로 결정이 됩니다.
이렇게 UIUserInterfaceSizeClass라는 enum안에 값들이 들어있고,
final class ParentViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
print(self.traitCollection.horizontalSizeClass) // compact
print(self.traitCollection.verticalSizeClass) // regular
}
}
이런식으로 접근이 가능합니다. (아이폰 12 프로 Max에서 돌린 값이에요)
이 그림만 봐도 알 수 있듯이, 아이폰의 경우,
portrait, landscape에 따라 Compact / Reguar가 바뀔 수 있습니다.
portrait에서는 vertical이 Regular였다면
landscape에서는 Compact가 되었죠.
이렇게 traitCollection이 변경될 때 시스템이 호출하는 메소드가
traitCollectionDidChange입니다.
그래서 이러한 trait이 변경되었을 때 custom한 일들을 해주고싶다면,
UITraitEnvironment을 준수하고있는 객체 안에서
traitCollectionDidChange를 재정의하여 사용하면 됩니다.
# traitCollectionDidChange
Q : previousTraitCollection?
A : 말 그대로 변경되기 이전의 traitCollection이 나오게 됩니다.
Dark -> light로 변경시 traitCollectionDidChange가 호출될텐데요,
previousTraitCollection의 userInterfaceStyle에는 Dark가 들어있는 그런식입니다.
Q : super.traitCollectionDidChange(previousTraitCollection)을 꼭 호출해줘야하나요?
A : 반드시 호출해줘야합니다. 구현을 시작할 때 super를 호출하여 view 계층 구조에서 더 높은 인터페이스 요소가 먼저 레이아웃을 조정할 수 있도록 하기 위함입니다.
At the beginning of your implementation, call super to ensure that interface elements higher
in the view hierarchy have an opportunity to adjust their layout first
자세한 사항은 traitCollectionDidChange문서를 참고하시길 바랍니다.