UIWindow
이번에는 코드로 UI를 그려보기로 결정했다.
아무도 나의 프로젝트를 막을 수 없다!
열심히 코드를 다 치고 시뮬레이터를 켰는데... 보이는 건 검은 화면 뿐이다.
대체 어떻게 된 걸까?
바로 코드로 작성한 설정이 실제 앱 화면에 적용되도록 전달하지 않았기 때문이다.
즉, 내 앱을 보여줄 기본 창이 설정되지 않은 것이다.
내가 코드로 작성한 설정을 앱 화면에 적용하려면 UIWindow
인스턴스를 생성해서 이 인스턴스에 내가 원하는 뷰와 설정을 할당해야 한다.
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let scene = (scene as? UIWindowScene) else { return }
window = UIWindow(windowScene: scene)
let nav = UINavigationController(rootViewController: FirstViewController())
window?.rootViewController = nav
window?.makeKeyAndVisible()
}
UIWindow
인스턴스를 만들고, 이걸 실제 화면과 연결하는 건 좋은데 정확히 이 객체는 어떤 역할을 하는가?
UIWindow
자체의 쓰임은 아래와 같다.
1. 다른 UIWindow
의 가시성에 영향을 줄 수 있는 z-index의 설정
2. 화면이 키보드 이벤트를 받아올 수 있도록 설정
3. 루트 뷰 컨트롤러를 수정할 때
// UIWindow의 뷰 컨트롤러에 접근
UIApplication.shared.windows.first?.rootViewController
대부분의 앱에서 UIWindow
는 하나의 화면만 있으면 충분하다.
외부 화면에 추가 콘텐츠를 보여주어야 할 때 UIWindow
는 하나 이상 만들어서 설정해줄 수 있다.
UIWindow
객체는 그 자체로 뷰가 없기 때문에 아무것도 보여지지 않는다.
이 객체의 루트 뷰 컨트롤러에 따라 UIWindow
위에 화면이 그려진다.
UIWindow
가 루트 뷰 컨트롤러를 받아온다고 해서 이들의 부모 클래스인 것은 아니다.
흥미롭게도 UIWindow
객체는 UIView
를 상속한다.
그리고 key window가 된 곳에서 발생하는 키보드 관련 이벤트를 받아올 수 있다.
이를 NotificationCenter
의 post
, addObserver
메소드의 Name
으로도 전달할 수 있다!
관련 이벤트가 굉장히 많기 때문에.. 공식 문서를 보고 필요할 때마다 찾아서 쓰는 게 좋아 보인다.
UIView
를 상속하는 하위 클래스 UIWindow
는 앱에 보여줄 뷰를 실제 앱 화면에 보여줄 수 있도록 받아오는 배경 역할을 하며, 앱 이벤트를 받아올 수 있다.makeKeyAndVisible()
로 화면을 보여주는 동시에 이벤트를 받아올 수 있게 해준다.window
를 앱에서 가질 수 있으며, 키보드 이벤트를 받아오기 위해선 key window
로 설정해야 한다.UIWindow
에서 사용자에 의해 일어난 키보드 관련 이벤트를 받아오는 Notification.Name
을 제공한다.애플 공식 문서 - UIWindow
Programmatically change rootViewController of storyBoard