[iOS] UIWindow
jane1choi opened this issue · 0 comments
UIWindow란?
The backdrop for your app’s user interface and the object that dispatches events to your views.
공식문서에 따르면, UIWindow는 앱의 사용자 인터페이스에 대한 배경(backdrop)이며, 뷰에 이벤트를 제공하는 객체입니다.
Windows는 이벤트를 처리하고 앱 작동에 기본적인 다른 많은 작업을 수행하기 위해 ViewController와 함께 작동합니다.
UIKit은 대부분의 Window 관련 상호 작용을 처리하며, 앱의 많은 동작(behaviors)을 구현하는 데 필요한 다른 객체와 함께 작동합니다.
Windows에는 고유한 시각적 모양(visual appearance)이 없지만, 앱 View의 프레젠테이션에 중요합니다.
Window는 Window의 RootViewController에서 관리하는 하나 이상의 View를 호스팅합니다.
스토리보드에서 RootViewController를 구성하고 인터페이스에 적합한 View를 추가합니다.
일반적으로 Xcode는 앱의 기본 Window를 제공합니다. 새로운 iOS 프로젝트는 스토리보드를 사용하여 앱의 View를 정의합니다. 스토리보드는 Xcode 템플릿이 자동으로 제공하는 AppDelegate 객체에 window 프로퍼티를 필요로 합니다. 앱에서 스토리보드를 사용하지 않는 경우, window를 직접 만들어야 합니다.
대부분의 앱에는 기본 화면에 앱의 콘텐츠를 표시하는 Window가 하나만 필요합니다.
장치의 기본 화면에 추가 창을 만들 수 있지만 추가 Window는 일반적으로 외부 화면에 콘텐츠를 표시하는 데 사용됩니다.
위의 이미지에서 알 수 있듯이 UIWindow는 스크린에 표시되는 뷰의 계층 구조에서 최상위에 위치한 뷰 입니다.
즉, Window객체는 뷰들을 담는 컨테이너라고 할 수 있습니다.
하지만!!! 위의 이미지에서 오해할 수 있는 점!!
UIWindow는 UIView의 부모이다??? 절대 네버 아님..
UIView가 UIWindow의 부모입니다!
정리하자면, UIWindow는 스토리보드를 사용할 경우 Xcode에서 기본으로 제공하며, 뷰들을 담는 컨테이너 역할을 하는 스크린의 최상위 뷰입니다. UIWindow는 ViewController와 함께 작동하며 이벤트를 전달하고 앱의 많은 동작들을 구현하는 데 중요한 역할을 하는 객체입니다. 또한, 앱의 생명 주기 동안 특별한 경우(외부 화면을 사용하는 경우)를 제외하면 단 하나의 window 객체만 생성하고 사용하며 표시한 뷰가 바뀌어야 되는 경우 가장 앞단에 있는 rootViewController의 교체를 통해 뷰를 바꾸는 방법을 사용합니다.
Window객체 만들기
일단, SceneDelegate 개념이 등장한 이후(iOS 13 이후)부터 SceneDelegate 오브젝트가 window 속성을 가지고 있습니다. (이전엔 AppDelegate)
위와 같이 SceneDelegate 에서 window 는 Optional 로 선언되어 있지만,
window 속성을 사용할 시점에는 제대로 초기화 되어있음을 보장합니다. (Xcode 가 자동으로 초기화시키기 때문)
하지만, 스토리보드를 사용하지 않고 코드로 UI 를 구성한다면, 윈도우를 직접 생성해야합니다.
SceneDelegate에서 window 객체를 만들어 화면을 초기화하는 방법에 대해 알아봅시다!
- window를 지정합니다.
SceneDelegate에 기본적으로 생성되어있는 window 프로퍼티에 UIWindowScene을 대입하여 window를 지정합니다. - rootViewController 지정
앱의 첫 화면이 될 window의 rootViewController를 지정해줍니다. - makeKeyAndVisible()
makeKeyAndVisible() 메서드를 이용해 keyWindow로 지정하고 Visible하도록 설정하여 window가 보일 수 있도록 해줍니다.
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(windowScene: windowScene) // 1. SceneDelegate의 프로퍼티에 window를 지정
let mainViewController = ViewController() // 맨 처음 보여줄 ViewController
window?.rootViewController = mainViewController // 2. rootViewController 지정
window?.makeKeyAndVisible() // 3. window 보이도록 설정
}