iOS 개발에서 UIWindow는 사용자 인터페이스의 필수 구성요소이다. 모든 뷰와 컨트롤이 표시되는 창이다. UIView는 뷰 관리 및 표시, 터치 이벤트 처리 및 애플리케이션의 전체적인 모양 관리를 담당한다.
UIWindow란
UIWindow는 UIView의 하위 클래스이며, iOS 애플리케이션의 View를 관리하고 표시하는 역할을 한다.
UIWindow는 View들을 담는 컨테이너며 Event를 전달해주는 매개체이다.
iOS앱은 콘텐츠를 화면에 보여주기위해 최소 1개 이상의 윈도우를 가지고 있다(보통1개)
애플리케이션이 시작될 때 시스템에 의해 자동으로 생성되며 앱의 첫 번째 뷰 컨트롤러 표시를 담당한다.
UIWindow의 역할
UIWindow객체는 iOS앱의 사용자 인터페이스를 관리하는데 중요한 역할을 한다. View를 나타내는 "액자"역할이다.
반드시 UIWindow가 있어야 View들을 나타낼 수 있다. UIWindow가 액자라면, 내부의 그림은 rootViewController가 된다.
(window의 rootViewController는 NavigationController, TabBarController, UIViewController 등이 될 수 있다.)
하지만 UIWindow자체는 시각적 요소가 없다. UIView를 상속받지만 window.background = .blue 같은 코드도 컴파일 가능하지만 아무런 변화는 없다.
새로운 화면을 나타낸다고 해서 새로운 window인스턴스를 생성하는것은 아니다. 대부분의 앱에서는 window가 단 한개만 사용된다.
UIWindow의 활용
- 앱 콘텐츠를 나타내기 위해 main window를 제공한다.
- 추가적으로 콘텐츠를 나타내기 위해 추가적인 window를 생성한다.
일반적으로 개발시에 다루는 윈도우는 windows[0]을 주로 사용하게 된다. 하지만 그 이외에도 윈도우가 생성되는 경우들이 있는데, 예를 들어 키보드는 올라올 때 마다 새로운 window를 생성하여 올라온다. 그리고 status bar도 하나으 window이다. alert도 window를 만들어 생성한다.
(iOS13부터 iPad가 multi window를 지원한다. 따라서 이를 위해 Scene Delegate가 추가되었다.)
UIWindow의기능적 책임
1. View 표시
UIWindow객체는 화면에 뷰와 컨트롤을 표시하는 역할을 한다. 추가할 나머지 사용자 인터페이스 구성요소에 대한 프레임워크를 제공한다.
2. 터치 이벤트 관리
UIWindow객체는 터치 이벤트를 처리하고 적절한 View 또는 Control에 전달한다. 터치 이벤트의 적중 테스트를 관리하고 이벤트를 수신해야하는 뷰 또는 컨트롤을 결정한다.
3. 방향 관리
UIWindow객체는 응용 프로그램의 방향을 관리한다. 장치 방향이 변경될 때 뷰 계층 구조를 회전하는 역할을 하며 방향이 변경되면 응용프로그램의 다른 객체에게 알림을 보낸다.
4. 모양 관리
UIWindow객체는 앱의 전체 모양을 관리하는 역할을 한다. 앱의 배경색을 제공하고, 수명, 신호 강도 및 시간과 같은 장치상태에 대한 정보를 표시하는 상태표시줄을 관리한다.
UIWindow의 사용 예
import UIKit
class ViewController: UIViewController {
var window: UIWindow?
override func viewDidLoad() {
super.viewDidLoad()
// Initialize the window object
window = UIWindow(frame: UIScreen.main.bounds)
// Create a view controller to display
let childViewController = ChildViewController()
// Add the child view controller to the window
window?.rootViewController = childViewController
// Make the window visible
window?.makeKeyAndVisible()
}
}
class ChildViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Create a label to display in the view
let label = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 50))
label.text = "Hello, World!"
label.textAlignment = .center
label.center = view.center
// Add the label to the view
view.addSubview(label)
}
}
이 예제에선 먼저 장치의 화면 크기로 UIWindow 클래스의 인스턴스를 만든다. 그런 다음 창의 rootViewController로 ChildViewController로 설정한다. 마지막으로 makeKeyAndVisable() 메서드를 호출하여 창을 표시한다.
이런 식으로 rootViewController를 변경한다.
실제로 코드로 UI를 작성하고 rootViewController를 변경하는 SceneDelegate