SceneDelegate가 UIResponder를 상속하는 이유

2025. 8. 25. 17:12·면접준비

왜 갑자기 UIScene이 등장했을까?

iOS 13이 출시되면서 가장 큰 변화 중 하나가 바로 UIScene의 도입이었습니다.

왜 Apple이 기존에 잘 작동하던 AppDelegate 구조를 바꿔가며 이런 복잡한 시스템을 도입했을까요? 🤔

핵심은 iPadOS의 멀티윈도우 지원 때문입니다.

기존 iOS에서는 하나의 앱이 하나의 화면(window)만 가질 수 있었지만, iPadOS부터는 하나의 앱이 여러 개의 윈도우를 동시에 띄울 수 있게 되었거든요.

예를 들어, Safari 앱을 두 개의 윈도우로 띄워서 하나는 YouTube를 보고 다른 하나는 문서를 작성하는 식으로 말이죠.

이런 상황에서 기존의 AppDelegate 하나로는 여러 개의 윈도우 생명주기를 관리하기가 까다로웠습니다.

그래서 Apple은 이렇게 역할을 분리했어요:

  • AppDelegate: 앱 전체의 생명주기 담당
  • SceneDelegate: 각각의 윈도우(Scene) 생명주기 담당

이제 하나의 앱에서 여러 윈도우가 독립적으로 작동할 수 있게 된 거죠

이제 좀 더 UIScene에 대해 들어가보겠습니다 

UIScene 시스템의 3가지 핵심 구성요소

UIScene 시스템을 이해하려면 이 세 가지 객체가 어떻게 협력하는지 알아야 합니다:

실제 예시로 이해해보겠습니다. iPad에서 Safari 앱으로 검색하면서 유튜브를 보겠습니다:)

1. UIScene = 실제 화면에 보이는 것

  • Safari 윈도우 A: YouTube가 열린 Scene 객체
  • Safari 윈도우 B: 문서 편집이 열린 Scene 객체
  • 각각이 하나의 UIScene 인스턴스가 되는거죠

2. UISceneSession  = 화면에 보이는 것의 설계도와 정보 관리

  • Safari 윈도우 A의 Session: "YouTube 페이지를 보고 있었음, 전체화면 모드, 볼륨 50%"
  • Safari 윈도우 B의 Session: "네이버에서 주식 검색중, 키보드 표시됨, 커서 위치 저장"

Scene이 메모리에서 사라져도 Session은 남아있어서, 나중에 윈도우를 다시 열 때 이전 상태 그대로 복원 가능!

3. UISceneDelegate 

  • Scene의 생명주기 이벤트를 처리하는 델리게이트

좀 더 이해가 쉽도록 어떻게 과정이 이루어지는 체크해 보겠슴다!

1단계: 사용자가 Safari에서 "새 윈도우" 버튼 터치

  • 시스템: “새로운 scene 필요하네!” → UISceneSession 생성 (윈도우를 어떻게 띄울지에 대한 설계도 역할)

2단계: Session 정보를 바탕으로 실제 윈도우 생성

  • 시스템: Session 정보 확인 → UIScene 생성 → SceneDelegate 연결 → 화면에 새 Safari 윈도우 등장!

3단계: 사용자가 윈도우 사용하다가 메모리 부족으로 시스템이 윈도우 종료

  • 시스템: SceneDelegate에게 "상태 저장해주세요" → Session에 현재 상태 저장 → UIScene 메모리에서 제거

4단계: 나중에 사용자가 다시 해당 윈도우 터치

 
  • 시스템: Session에서 저장된 상태 확인 → 새로운 UIScene 생성 → 이전 상태 그대로 복원! (YouTube 동영상 이어보기 가능)

클래스 계층구조 뜯어보기

UIScene의 상속 구조

코드를 타고 들어가보면 UIScene은 UIResponder를 상속하고 있네요?

그러면 UIResponder는 뭘까요?

우선 터치 이벤트, 모션 이벤트 등 유저가 하는 이벤트들이 발생하면 UIKit은 앱의 응답자 객체들에게 전달하여 처리하도록 합니다.

그 응답자 객체가 바로 UIResponder를 상속하고 있는 객체들인 거죠. 

UIResponder를 상속하고 있는 서브클래스들을 보면:

  • UIApplication: 앱 자체에서 받고
  • UIViewController: 뷰컨트롤러들도 받고
  • UIView: 모든 뷰들이 받고
  • UIScene: Scene들이 받게 되는거죠

그러면 저걸 상속하게 되면 어떻게 되는가? 라고 물어본다면

1. 터치 이벤트 (Touch Events): 

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?)
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?)
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?)
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?)

터치에 관한 메서드들을 사용할 수 있고,

2. 모션 이벤트 (Motion Events): 디바이스 흔들기 등

override func motionBegan(_ motion: UIEvent.EventSubtype, with event: UIEvent?)
override func motionEnded(_ motion: UIEvent.EventSubtype, with event: UIEvent?)

3. 프레스 이벤트 (Press Events): 외부 키보드, 리모컨 등

4. 원격 제어 이벤트 (Remote Control Events): 음악 재생 컨트롤 등

First Responder Chain의 핵심 동작 원리

그러면 이벤트가 발생하면 어디서 처리해야할지는 어떻게 알 수 있을까요?

바로 Responder Chain에 의해 이벤트를 처리할 객체를 찾아가는 구조입니다!

이 중에 First Responder는 이벤트를 가장 먼저 받을 수 있는 응답자를 의미합니다

  • 텍스트 필드 탭 -> UITextField가 First Responder

이벤트 전달 흐름 

이벤트가 발생하면 다음 순서로 처리됩니다:

  1. 터치 이벤트의 경우:(iOS 13+기준)
     
    터치된 뷰 → 상위 뷰 → 상위 뷰 → 뷰 컨트롤러 → UIWindow → UIWindowScene → UIApplication → UIApplicationDelegate
  2. 기타 이벤트의 경우:
     
    First Responder → Next Responder → Next Responder → ... → UIApplication

SceneDelegate가 UIResponder를 상속하는 진짜 이유

자, 이제 궁금증의 핵심에 도달했습니다! Xcode에서 새 프로젝트를 만들면 SceneDelegate가 이렇게 생겼죠:

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    var window: UIWindow?
    // ...
}

iPad에서 같은 앱의 두 개 윈도우가 열려있을 때를 생각해보세요:

  • 윈도우 A: 키보드 입력을 받는 중
  • 윈도우 B: Apple Pencil 이벤트를 처리하는 중
  • 각각 다른 외부 키보드 단축키를 처리해야 하는 상황

이런 경우 Scene별로 독립적인 Responder Chain을 가져야 하니까,

 UIScene과 SceneDelegate 모두 UIResponder를 상속하는 구조가 필요한 거였어여

 

이후의 역할도

'면접준비' 카테고리의 다른 글

근본으로돌아가자(7)-String,Array으로 시작해서 Sequence까지  (0) 2025.04.04
Metal(2)-셰이더 코드 작성까지  (0) 2025.04.02
Metal(1)- 메탈을 알기전에 필요한 것들  (1) 2025.03.29
Autolayout 모든 것: 사이클부터 제약조건까지  (0) 2025.03.26
Apple의 보안  (0) 2025.03.15
'면접준비' 카테고리의 다른 글
  • 근본으로돌아가자(7)-String,Array으로 시작해서 Sequence까지
  • Metal(2)-셰이더 코드 작성까지
  • Metal(1)- 메탈을 알기전에 필요한 것들
  • Autolayout 모든 것: 사이클부터 제약조건까지
2료일
2료일
좌충우돌 모든것을 다 정리하려고 노력하는 J가 되려고 하는 세미개발자의 블로그입니다. 편하게 보고 가세요
  • 2료일
    GPT에게서 살아남기
    2료일
  • 전체
    오늘
    어제
    • 분류 전체보기 (122) N
      • SWIFT개발 (29)
      • 알고리즘 (25)
      • Design (6)
      • ARkit (1)
      • 면접준비 (31) N
      • UIkit (2)
      • Vapor-Server with swift (3)
      • 디자인패턴 (5)
      • 반응형프로그래밍 (12)
      • CS (3)
      • 도서관 (2) N
  • 인기 글

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
2료일
SceneDelegate가 UIResponder를 상속하는 이유
상단으로

티스토리툴바