main() 실행UIApplicationMain() 호출 → iOS 앱의 런타임 진입점UIApplication 객체 생성 (앱의 본체)AppDelegate 객체 생성 및 RunLoop 준비application(_:didFinishLaunchingWithOptions:) 호출SceneDelegate 통해 UI 표시앱 시작 시 AppDelegate, SceneDelegate, RunLoop가 함께 구성된다.
Application Scene ManifestEnable Multiple Windows = NODelegate Class Name = $(PRODUCT_MODULE_NAME).SceneDelegateMain Interface 항목 제거 필요 (Build Settings → Info.plist Values)Could not find a storyboard named 'Main'❗ AppDelegate에서 과도한 초기화 작업은 지양 (UI 표시 전 blocking 위험)
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions)
UIWindowScene: UIScene의 서브클래스로, 하나 이상의 UIWindow를 관리| 상태 | 설명 |
|---|---|
| Not Running | 앱이 실행되지 않거나 종료된 상태 |
| Inactive | 실행 중이지만 이벤트는 받지 않음 (예: 재난문자) |
| Active | 앱이 포그라운드에서 정상 작동 중 |
| Background | 백그라운드에서 작업 중 (예: 음악 재생) |
| Suspended | 백그라운드에서 멈춘 상태 (메모리 해제 대상) |
func sceneDidBecomeActive(_ scene: UIScene)
func sceneWillResignActive(_ scene: UIScene)
| 메서드 | 설명 |
|---|---|
loadView() | 뷰 객체를 생성할 때 호출 (직접 구현할 일 드묾) |
viewDidLoad() | 뷰가 메모리에 올라온 직후 1회만 호출됨 |
viewWillAppear() | 뷰가 화면에 나타나기 직전, 매번 호출됨 |
viewDidAppear() | 뷰가 화면에 완전히 나타난 직후 |
viewWillDisappear() | 뷰가 화면에서 사라지기 직전 |
viewDidDisappear() | 뷰가 완전히 사라진 직후 |
일반적으로는
viewDidLoad,viewWillAppear,viewDidAppear를 주로 사용.
override func viewDidLoad() {
super.viewDidLoad()
print("🔥 viewDidLoad 호출됨")
}
UILabel → UIView → UIViewController → UIWindow → UIApplication → AppDelegate
UILabel이 터치 이벤트를 처리하지 않으면 → superview인 UIView로 전달
그 후 ViewController → UIWindow → UIApplication 순으로 올라간다
특정 지점(Point)에 대한 터치 이벤트가 어떤 뷰(View)에 닿았는지를 판별하는 메서드이다.
터치 위치에 가장 가까운(깊은 계층의) 뷰가 이벤트에 응답하게 됨
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
// 이벤트를 받을 View를 결정
return super.hitTest(point, with: event)
}
| 조건 | 설명 |
|---|---|
isHidden == false | 뷰가 화면에 보여야 함 |
alpha > 0.01 | 뷰가 충분히 불투명해야 함 |
isUserInteractionEnabled == true | 사용자 인터랙션이 가능해야 함 |
위 조건들을 변경해가며 어떤 뷰가 이벤트를 받는지 실험해보기
View 계층 구조를 따라 이벤트가 어떻게 전달되는지 로그로 추적해보기
func sceneDidBecomeActive(_ scene: UIScene) {
print("🌞 Scene이 Active 상태로 진입")
}
func sceneWillResignActive(_ scene: UIScene) {
print("🌙 Scene이 Inactive 상태로 전환")
}
override func viewDidLoad() {
super.viewDidLoad()
print("📌 viewDidLoad 호출됨")
}
override func viewWillAppear(_ animated: Bool) {
print("📌 viewWillAppear 호출됨")
}

hitTest 커스터마이징 실습
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
print("📍 \(self)의 hitTest 실행")
return super.hitTest(point, with: event)
}