JosephCha의 개발일지

UIKit 기본개념 본문

iOS

UIKit 기본개념

JosephCha 2023. 8. 9. 14:48
반응형

UIKit 기본개념

  • iOS, iPadOS, tvOS 앱을 위한 그래픽 이벤트 기반 UI(사용자 인터페이스)를 구축하고 관리해주는 프레임 워크
  • iOS, iPadOS, tvOS앱의 핵심 인프라를 구성하는 데 사용할 수 있는 구성 요소를 포함하여 앱을 구축하기 위한 다양한 기능을 제공함
  • UI를 구현하기 위한 Window및 View Architecture을 제공
  • 앱에 멀티 터치 및 기타 유형의 입력을 제공하기 위한 이벤트 처리 인프라 제공
  • 사용자, 시스템 및 앱 간의 상호 작용을 관리하기 위한 Main run loop 제공
  • 애니메이션, 문서, 드로잉 및 인쇄, 텍스트 관리 및 디스플레이, 검색, 앱 확장, 리소스 관리 및 현재 장치에 대한 정보 얻기를 지원
  • 접근성 지원을 사용자 정의, 다른 언어, 국가 또는 문화 지역에 맞게 앱의 인터페이스를 현지화할 수 있음
해당 클래스에 대한 문서에 달리 명시되지 않는 한, 앱의 Main Thread 또는 Main Dispatch Queue에서만 Uikit 클래스를 사용
하셈. 이 제한은 특히 UIResponder에서 파생되거나 어떤식으로든 앱의 사용자 인터페이스를 조작하는 클래스에 적용됨
시스템은 앱 번들안에 있는 Info.plist 파일을 통해 앱의 구성 및 기능에 대한 정보를 도출함

Structure of APP

UIKit 앱의 상당히 전형적인 구조를 나타냄

  • UIKit은 앱의 View layer들과 Controller 안의 대부분의 object들을 제공함. 특히, 일반적으로 화면에 콘텐츠를 표시하는 UiView 클래스를 정의함(Metal 및 기타 시스템 프레임워크를 사용해 콘텐츠를 화면에 직접 렌더링 할 수도 있음)
  • UIApplication 객체는 앱의 Main Event Loop를 실행하고 앱의 전체 수명 주기를 관리함
    • UIApplication은 iOS에서 실행되는 앱의 중앙 집중식 제어 및 조정 지점

Main Run Loop

  • Main run loop는 이벤트들을 받은 순서대로 처리한다.
  • UIApplication 객체는 앱이 실행될 때, Main run loop를 실행하고 해당 run loop로 이벤트를 처리하게됨
  • 사용자가 디바이스에서 특정 액션을 취하면, 그 액션에 해당하는 이벤트가 시스템에 의해 생성되어 UIKit에서 생성한 port를 통해 앱에 전달됨
  • 그리고 전달된 이벤트들은 queue에 하나씩 보관되었다가 main run loop로 전달되어서 처리가 된다.

(해당 과정은 당연히 mainThread에서 동작)

App and environment

앱의 Life-Cycle 이벤트들과 UI Scene들을 관리하고, 앱이 실행되는 특성과 환경에 대한 정보를 얻음

iOS 13부터 동시에 앱의 UI 객체를 여러개 관리하고 만들수 있음, 또한 App Switcher를 통해 스위칭 가능. iPad에선 나란히 여러 앱의 객체들을 화면에 띄울 수 있음. UI의 각 인스턴스는 다른 콘텐츠를 표시하거나, 동일한 콘텐츠를 다른 방식으로 표시함. 예를 들어, 특정 날을 보여주는 캘린더 앱의 한 인스턴스를 표시할 수 있고, 한 달 전체를 보여주는 또 다른 인스턴스를 표시할 수 있음. UIKIt은 장치 설정, 인터페이스 설정, 사용자 환경설정의 조합을 반영하는 trait collection을 사용하여 현재 환경에 대한 세부 사항을 전달함. 예를 들어, 특성을 사용하여 현재 View 또는 ViewController에서 다크 모드가 활성화 되어 있는지 감지. 현재 환경에 따라 콘텐츠를 사용자 정의하려면 UIView 또는 UIViewController 객체의 현재 trait collection을 참조

Managing your app’s life cycle

앱이 foreground 또는 background에 있을 때 시스템 알림들에 응답하고 다른 중요한 시스템 관련 이벤트를 처리함

개요

앱의 현재 상태는 언제든지 할수 있는 것과 할 수 없는 것을 결정함. 예를들어, foreground 앱은 사용자의 관심을 끌기 때문에 CPU를 포함한 시스템 리소스보다 우선 순위가 있음. 그에 반해, 백그라운드 앱은 가능한 한 적은 작업을 해야 하며, 가급적이면 아무것도 하지 않아야 함. 왜냐하면 offscreen이기 때문. 앱이 상태에서 상태로 바뀌면, 그에 따라 동작을 조정해야 함
  • iOS 13이상에선, UISceneDelegate 객체를 사용하여 scene 기반 앱의 life-cycle 이벤트들에 응답함
  • iOS 12이하에선, UIApplicationDelegate 객체를 사용하여 life-cycle 이벤트들에 응답함

Scene 기반 life-cycle 이벤트 대응

앱이 Scene들을 지원하는 경우, UIKit은 각각에 대해 별도의 life-cycle 이벤트를 제공함. 하나의 scene은 device에서 실행되는 앱 UI의 하나의 인스턴스를 나타냄. 사용자는 각각의 앱에 대한 다수의 Scene들을 생성할 수 있고 별도로 표시하고 숨길 수 있음. 각 Scene들에는 고유한 life-cycle이 있기에, 각각 다른 상태에 있을 수 있음. 예를 들어, 한 Scene은 foreground에 있고 다른 Scene은 background에 있거나 정지될 수 있음

사용자나 시스템이 앱의 새로운 Scene을 요청할 때, UIKit은 Scene을 만들고 Unattached 상태로 넣음. 사용자가 요청한 Scene은 화면에 나타나는 Foreground로 빠르게 이동. 시스템에서 요청한 Scene은 일반적으로 이벤트를 처리할 수 있도록 Background로 이동함. 예를들어, 위치 이벤트를 처리하기 위해 백그라운드에서 Scene를 launch할 수 있음. 사용자가 앱의 UI를 닫을 때, UIKit은 관련된 Scene을 Background 상태로 이동시키고 결국 Suspended 상태로 이동함. UIKit은 언제든지 Background나 Suspended Scene을 분리하여 자원을 되찾을 수 있으며, 그 Scene을 Unattached 상태로 되돌릴 수 있음

Scene들의 상태 전환

Scene 전환을 사용하여 다음 task들을 수행하십시오

  • UIKit이 Scene을 앱에 연결할 때, Scene의 초기 UI를 구성하고 Scene에 필요한 데이터를 로드함
  • Foreground-active 상태로 전환할 때, UI를 구성하고 사용자와 상호 작용할 준비를 함. Foreground에서 실행되도록 UI를 준비해보시오
  • Foreground-active 상태를 떠나면, 데이터를 저장하고 앱의 동작을 조용하게 해보시오. Background에서 실행되도록 UI 준비하는 것을 보시오
  • Background 상태에 들어가면, 중요한 작업을 완료하고, 가능한 많은 메모리를 확보하고 앱 스냅샷을 준비하십시오. Background에서 실행되도록 UI 준비하는 것을 보시오.
  • Scene 연결이 끊어지면, Scene과 관련된 공유 리소스를 정리하시오.
  • Scene 관련 이벤트 외에도, UIApplicationDelegate 객체를 사용하여 앱 실행에 응답 해야함. 앱 실행 시 해야 할 일에 대한 정보는 앱 실행에 대한 응답을 참조 하십시오

앱 기반 life-cycle 이벤트 대응

iOS 12 이전에는, Scene을 지원하지 않는 앱에서 UIKit은 모든 수명 주기를 이벤트를 UIApplicationDelegate 객체로 제공함. AppDelegate는 별도의 화면에 표시되는 window를 포함하여 앱의 모든 window들을 관리함. 결과적으로 앱 상태 전환은 외부 디스플레이의 콘텐츠를 포함하여 앱의 전체 UI에 영향을 미침

다음 그림은 AppDelegate와 관련된 상태 전환을 보여줌. 앱 실행 후, 시스템은 UI가 화면에 나타날지 여부에 따라 앱을 inActive 또는 Background 상태로 놓음. Foreground로 시작할 때, 시스템은 앱을 자동으로 active 상태로 전환함. 그 후, 상태는 앱이 종료될 때까지 active와 Background 사이에서 변동함

앱 전환을 사용하여 다음 작업을 수행하십시오

  • 앱 실행 시, 앱의 데이터 구조와 UI를 초기화하셈. 앱 실행에 대한 응답을 보셈
  • 활성화(Active) 시, UI 구성을 완료하고 사용자와 상호 작용할 준비를 하셈. Foreground에서 실행되도록 UI를 준비하기를 보셈
  • 비활성화(deactive) 시, 데이터를 저장하고 앱의 동작을 조용히 하셈. Background에서 실행되도록 UI 준비하기를 보셈
  • Background 상태로 들어가면, 중요한 작업을 완료하고, 가능한 한 많은 메모리를 확보하고, 앱 스냅샷을 준비함. Background에서 실행되도록 UI준비하기를 보셈
  • 종료 시, 모든 작업을 즉시 중단하고 공유 자원을 해제함. applicationWillTerminate(_:)를 확인하셈

다른 중요한 이벤트에 대응

수명 주기 이벤트를 처리하는 것 외에도, 앱은 다음표에 나열된 이벤트를 처리할 준비가 되어 있어야 함. UIApplicationDelegate 객체를 사용하여, 이러한 이벤트의 대부분을 처리하면됨. 경우에 따라 알림을 사용하여 처리할 수 있으므로 앱

메모리 경고 이벤트앱의 메모리 사용량이 너무 높을 때 이벤트를 받음.   https://developer.apple.com/documentation/uikit/app_and_environment/managing_your_app_s_life_cycle/responding_to_memory_warnings를 참고하셈
보호된 데이터를 사용할 수 있음/사용할 수 없음에 대한 이벤트 사용자가 단말을 잠그거나 잠금을 해제할 때 이벤트를 받음 https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623044-applicationprotecteddatadidbecom 와 https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623019-applicationprotecteddatawillbeco를 참고하셈
Handoff taks NSUserActivity 객체를 처리해야 할 때 이벤트를 받음 https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1622963-application를 참고하셈
시간 변화 전화 통신사가 시간 업데이트를 보낼 떄와 같은 몇 가지 다른 시간 변경 이벤트를 받음 https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1622992-applicationsignificanttimechange를 참고하셈
Open URLs 앱이 Resource를 열어야할 때 이벤트를 받음 https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623112-application를 참고하셈

Touches, presses, and gestures

앱의 이벤트 처리 로직을 gesture recognizers에 캡슐화하여 앱 전체에서 해당 코드를 재사용할 수 있음

개요

전형적인 UIKit view들과 control들을 사용해 앱을 빌드하면, UIKit은 자동으로 touch event들을 핸들링함(멀티터치 이벤트 포함). Custom View를 사용해 콘텐츠를 표시하는 경우, view에서 발생하는 모든 터치 이벤트를 처리해야 함. 터치 이벤트를 직접 처리하는 두가지 방법이 있음.

Using responders and the responder chain to handle events

앱을 통해 전파되는 이벤트를 처리하는 방법을 배워보자

개요

앱은 responder 객체들을 사용해 이벤트들을 수신하고 처리함. responder 객체는 UIResponder 클래스의 인스턴스이며, 일반적인 하위 클래스에는 UIView, UIViewController 및 UIApplication이 포함됨. Responder는 raw 이벤트 데이터를 받고 이벤트를 처리하거나 다른 Responder 객체로 전달해야 함. 앱이 이벤트를 받으면, UIKit은 자동으로 해당 이벤트를 첫번째 Responder로 알려진 가장 적정한 응답자 객체로 전달함. 처리되지 않은 이벤트는 앱의 Responder 객체의 동적 구성인 active responder chain에서 Responder에서 responder로 전달됨.

다음 그림은 인터페이스에 label, text field, button 및 두 개의 background view가 포함된 앱의 responder를 보여줌. 이 다이어그램은 또한 하나의 responder에서 다음 responder로 이동하는 방법을 보여줌

 

  1. text field가 이벤트를 처리하지 않으면, UIKit은 이벤트를 text field의 부모 UIView 객체(window의 root view를 따르고 있는)에 이벤트를 보냄
  2. root view에서 responder chain은 이벤트를 window로 안내하기 전에 소유한 ViewController로 전환함
  3. window가 이벤트를 처리할 수 없는 경우, UIKit은 이벤트를 UIApplication 객체로 전달하고, 만약 해당 객체가 UIResponder의 인스턴스이고 아직 responder chain의 일부가 아닌 경우 app delegate에게 전달함

이벤트의 first responder 결정

  • UIKit은 해당 이벤트의 타입에 따라 객체를 이벤트의 first responder로 지정함. 이벤트 타입은 다음과 같음
이벤트 타입 First Responder
Touch events 터치가 발생한 View
Press events 포커스를 가진 객체
Shake-motion events 지정한 객체(또는 UIKit)
Remote-control events 지정한 객체(또는 UIKit)
Editing menu messages 지정한 객체(또는 UIKit)

Touches, presses, and gestures

앱의 이벤트 처리 로직을 gesture recognizers에 캡슐화하여 앱 전체에서 해당 코드를 재사용할 수 있음

개요

전형적인 UIKit view들과 control들을 사용해 앱을 빌드하면, UIKit은 자동으로 touch event들을 핸들링함(멀티터치 이벤트 포함). Custom View를 사용해 콘텐츠를 표시하는 경우, view에서 발생하는 모든 터치 이벤트를 처리해야 함. 터치 이벤트를 직접 처리하는 두가지 방법이 있음.

Using responders and the responder chain to handle events

 

앱을 통해 전파되는 이벤트를 처리하는 방법을 배워보자

 

개요

앱은 responder 객체들을 사용해 이벤트들을 수신하고 처리함. responder 객체는 UIResponder 클래스의 인스턴스이며, 일반적인 하위 클래스에는 UIView, UIViewController 및 UIApplication이 포함됨. Responder는 raw 이벤트 데이터를 받고 이벤트를 처리하거나 다른 Responder 객체로 전달해야 함. 앱이 이벤트를 받으면, UIKit은 자동으로 해당 이벤트를 첫번째 Responder로 알려진 가장 적정한 응답자 객체로 전달함. 처리되지 않은 이벤트는 앱의 Responder 객체의 동적 구성인 active responder chain에서 Responder에서 responder로 전달됨.

 

다음 그림은 인터페이스에 label, text field, button 및 두 개의 background view가 포함된 앱의 responder를 보여줌. 이 다이어그램은 또한 하나의 responder에서 다음 responder로 이동하는 방법을 보여줌

 

 

  1. text field가 이벤트를 처리하지 않으면, UIKit은 이벤트를 text field의 부모 UIView 객체(window의 root view를 따르고 있는)에 이벤트를 보냄
  2. root view에서 responder chain은 이벤트를 window로 안내하기 전에 소유한 ViewController로 전환함
  3. window가 이벤트를 처리할 수 없는 경우, UIKit은 이벤트를 UIApplication 객체로 전달하고, 만약 해당 객체가 UIResponder의 인스턴스이고 아직 responder chain의 일부가 아닌 경우 app delegate에게 전달함

 

이벤트의 first responder 결정

UIKit은 해당 이벤트의 타입에 따라 객체를 이벤트의 first responder로 지정함. 이벤트 타입은 다음과 같음

이벤트 타입 First Responder
Touch events 터치가 발생한 View
Press events 포커스를 가진 객체
Shake-motion events 지정한 객체(또는 UIKit)
Remote-control events 지정한 객체(또는 UIKit)
Editing menu messages 지정한 객체(또는 UIKit)
가속도계, 자이로스코프 및 자력계와 관련된 Motion 이벤트는 responder chain을 따르지 않음. 대신 Core Motion이 해당 이벤트들을 지정된 객체에 직접 전달함. 자세한 내용은 Core Motion Framework 참고
  • 컨트롤은 action message를 사용하여 관련 target 객체와 직접 통신함.
  • 사용자가 컨트롤과 상호 작용할 때, 컨트롤은 대상 객체에 action message를 보냄
  • action message는 이벤트가 아니지만, 여전히 responder chain을 이용할 수 있음
  • 컨트롤의 target 객체가 nil일 때, UIKit은 target 객체에서 시작하여 적절한 작업 방법을 구현하는 객체를 찾을 때까지 responder chain을 통과함. 예를들어, UIkit editing message는 이 동작을 사용하여 cut(*:), copy(:) 또는 paste(_:)*와 같음 이름으로 메서드를 구현하는 responder 객체를 검색함
  • Gesture recognizer는 View가 하기 전에 press/touch 이벤트를 받음
  • View의 gesture recognizer가 일련의 터치를 인식하지 못하면, UIKit은 터치를 View로 보냄
  • View가 터치를 처리하지 않으면, UIkit은 그것들을 responder chain으로 전달함

더 많은 정보는 Handling UIKit gestures 참고

터치 이벤트가 포함된 Responder 결정

UIKit은 View 기반 hit-testing을 사용하여 터치 이벤트가 발생하는 위치를 결정함. 특히, UIKit은 View-hierarchy의 View 객체의 bound와 터치된 위치를 비교함. UIView의 https://developer.apple.com/documentation/uikit/uiview/1622469-hittest메소드는 View-hierarchy 구조를 가로지르며, 터치 이벤트의 first responder가 되는 지정된 터치를 포함하는 가장 깊은 하위 View를 찾아줌.

터치 위치가 View의 범위를 벗어나면, hitTest 메소드는 해당 View와 모든 하위 View를 무시함. 결과적으로, View의 clipsToBounds 속성이 참일 때, 그 View의 bound 밖의 하위 View는 터치를 포함하더라도 반환되지 않음(무시됨).

터치가 발생하면, UIKit은 UITouch 객체를 만들고 View와 연결함. 터치 위치 또는 기타 매개 변수가 변경됨에 따라, UIKit은 새로운 정보로 동일한 UITouch 객체를 업데이트 함. 변하지 않는 유일한 속성은 View임 (터치 위치가 View 외부로 이동하더라도, 터치의 View 속성의 값은 변하지 않음). 터치가 끝나면, UIKit은 UITouch 객체를 해제함.

Responder Chain 변경

responder 객체의 next 프로퍼티를 재정의하여 responder chain을 변경할 수 있음. 이럴 때, next responder는 당신이 반환하는 대상임(?)

많은 UIKit 클래스는 이미 이 프로퍼티를 재정의하고 다음과 같은 특정 객체를 반홤함

  • UIView 객체
    • View가 ViewController의 루트View인 경우, next responder는 ViewController임. 그렇지 않으면, next responder는 View의 슈퍼View임
  • UIViewController 객체
    • ViewController의 View가 Window의 루트 View인 경우, next responder 는 window 객체임
    • ViewController가 다른 ViewController에 의해 present된 경우, next responder는 presenting한 View Controller 임
  • UIWindow 객체
    • window의 next responder는 UIApplication 객체
  • UIApplication 객체
    • next responder는 App Delegate지만, App Delegate가 UIResponder의 인스턴스이고 View, ViewController 또는 앱 객체 자체가 아닌 경우에만 가능

참고: https://developer.apple.com/documentation/uikit

'iOS' 카테고리의 다른 글

네트워크 Endpoint  (0) 2023.08.09
iOS 동작과정  (0) 2023.08.09
객체지향 프로그래밍  (0) 2023.02.08
Content Hugging priority & Content Compression Resistance priority  (0) 2021.11.29
MVC 패턴  (0) 2021.11.22
Comments