본문 바로가기

All Categories/iOS & Swift

iOS) UIViewController 살펴보기, lifecycle

반응형

안녕하세요 재희입니다. UIViewController 애플 문서를 살펴보겠습니다.

 

Apple Developer Documentation

 

developer.apple.com


UIViewController

UIKit 앱의 view hierarchy를 관리하는 object입니다.

선언

@MainActor class UIViewController : UIResponder

개요

UIViewController 클래스는 모든 뷰 컨트롤러에 공통적인 shared behavior를 정의합니다.

UIViewController 클래스의 인스턴스를 직접 만드는 경우는 거의 없습니다.

대신 UIViewController를 하위 분류하고, 뷰 컨트롤러의 view hierarchy를 관리하는 데 필요한 메소드와 속성을 추가합니다.

 

뷰 컨트롤러의 주요 업무는 다음과 같습니다:

  • 일반적으로 기저를 이루는 데이터의 변경에 따른 view의 contents 업데이트
  • view를 통한 user interaction 응답
  • view 크기 조정 및 전체 인터페이스의 레이아웃 관리
  • 앱의 다른 object(다른 뷰 컨트롤러 포함)와의 조정(coordinating)

 

뷰 컨트롤러는 관리하는 뷰에 단단히 바인딩되어 view hierarchy에서 이벤트를 처리합니다.

특히, 뷰 컨트롤러는 UIResponder(이벤트에 응답하고 처리하기 위한 추상 인터페이스)의 객체이며, 뷰 컨트롤러의 root view와 일반적으로 다른 뷰 컨트롤러에 속하는 뷰의 superview 사이의 responder chain에 삽입됩니다.

만약 이벤트를 처리하는 뷰 컨트롤러의 뷰가 없다면, 뷰 컨트롤러는 이벤트를 처리하거나 superview로 전달할 수 있습니다.

 

뷰 컨트롤러는 독립적으로 거의 사용되지 않습니다.

대신 앱의 user interface의 일부를 각각 소유하는 여러 뷰 컨트롤러를 사용하는 경우가 많습니다.

예를 들어, 한 뷰 컨트롤러는 item의 table을 보여주고 다른 뷰 컨트롤러를 해당 테이블에서 선택한 항목을 표시할 수 있습니다.

일반적으로 한 번에 하나의 뷰 컨트롤러의 뷰만 볼 수 있습니다.

뷰 컨트롤러는 새로운 뷰 집합을 표시하기 위해 다른 뷰 컨트롤러를 제공할 수도 있고, 원하는 대로 다른 뷰 컨트롤러의 content 및 animation view를 위한 컨테이너 역할을 할 수 있습니다.

View Controller Programming Guide for iOS

 

View Management

뷰 컨트롤러는 그들의 뷰를 느리게 로드합니다.

view 프로퍼티에 처음 액세스하면 뷰 컨트롤러의 뷰가 로드되거나 생성됩니다.

 

뷰 컨트롤러에 대한 뷰를 지정하는 방법:

  • Storyboard에서 뷰 컨트롤러와 해당 뷰를 지정

스토리보드를 사용하여 뷰와 뷰 컨트롤러에 대한 연결을 지정합니다.

뷰 컨트롤러 간의 관계 및 segue를 지정하여 앱의 동작을 더 쉽게 보고 수정할 수 있습니다.

스토리보드에서 뷰 컨트롤러를 로드하려면 적절한 UIStoryboard object의 instantiateViewController(withIdentifier:) method를 호출합니다.

스토리보드 객체는 뷰 컨트롤러를 만들고 코드로 반환합니다.

 

  • Nib file을 사용하여 뷰 컨트롤러에 대한 뷰를 지정

nib file을 사용하면 단일 뷰 컨트롤러의 view를 지정할 수 있지만 뷰 컨트롤러 간의 관계나 segue는 정의할 수 없습니다.

또한 nib file에는 뷰 컨트롤러에 대한 최소한의 정보만 저장됩니다.

nib file을 사용하여 뷰 컨트롤러 object를 초기화하려면 뷰 컨트롤러 클래스를 프로그래밍 방식으로 만든 후 init(nibName:bundle:)  메소드를 사용하여 초기화 해야 합니다.

뷰가 요청되면 뷰 컨트롤러가 nib file에서 뷰를 로드합니다.

 

  • loadView() 메소드를 사용하여 뷰 컨트롤러에 대한 뷰를 지정

view hierarchy을 프로그래밍 방식으로 작성하고 해당 계층의 root view를 뷰 컨트롤러의 뷰 property에 할당합니다.

 

이러한 모든 기법은 모두 동일한 최종 결과를 가집니다.

Auto Layout Guide

 

뷰 관련 Notification 처리

view의 visibility가 변경되면, 뷰 컨트롤러는 하위 클래스가 변경에 대응할 수 있도록 자체 메소드를 자동으로 호출합니다.

viewWillAppear(_:)와 같은 메소드를 사용하여 view가 화면에 나타나도록 준비하고, viewWillDisappear(_:)를 사용하여 변경사항 또는 기태 상태 정보를 저장합니다.

Vaild State Transitions

위 그림은 뷰 컨트롤러의 뷰에 대해 가능한 visible state와 발생할 수 있는 state transition을 보여줍니다.

모든 'will' 콜백 메소드가 'did' 콜백 메서드와만 쌍을 이루지는 않습니다.

'will' 콜백 방법으로 프로세스를 시작하는 경우, 해당하는 'did' 콜백 방식과 반대되는 'will' 콜백 방법 모두에서 프로세스를 종료해야 합니다.


loadView()

컨트롤러가 관리하는 view를 생성합니다.

Discussion

절대 이 메소드를 직접 호출해서는 안 됩니다.

view property가 요청되었지만 현재 nil인 경우 뷰 컨트롤러가 이 메소드를 호출합니다.

이 메소드는 뷰를 로드하거나 만들어 view property에 지정합니다.

 

Interface Builder를 사용하여 view를 생성하고 뷰 컨트롤러를 초기화하는 경우 이 메소드를 override하면 안 됩니다.

 

view를 수동으로 작성하기 위해 이 메소드를 override할 수 있씁니다.

view hierarchy의 root view를 view property에 지정합니다.

생성한 view는 고유한 인스턴스여야 하며 다른 뷰 컨트롤러 object와 공유해서는 안 됩니다.

이 메소드의 custom implementation은 super를 호출하지 않아야 합니다.

 

viewDidLoad()

컨트롤러 view가 메모리에 로드되면 호출됩니다.

Discussion

이 메소드는 뷰 컨트롤러가 해당 view hierarchy를 메모리에 로드한 후 호출됩니다. (단 한 번)

view hierarchy 가 nib file에서 로드되었는지 loadView() 메소드에서 프로그래밍 방식으로 만들어졌는지 여부에 관계없이 호출됩니다.

일반적으로 nib file에서 로드된 뷰에 대해 추가 초기화를 수행하려면 이 방법을 override 합니다.

(view의 bounds가 설정되지 않은 상태, 화면에 표시 x)

 

viewWillAppear(_:)

뷰 컨트롤러에 뷰를 view hierarchy에 추가하려고 함을 알립니다. (화면에 나타나기 직전)

Parameters

animated: true이면 애니메이션을 사용하여 view가 window에 추가됩니다.

Discussion

이 메소드는 뷰 컨트롤러의 뷰를 view hierarchy에 추가하기 전과 view를 표시하도록 애니메이션이 구성되기 전에 호출됩니다.

이 메소드를 override하여 view display와 관련된 사용자 지정 작업을 수행할 수 있습니다.

예를 들어, 이 메소드를 사용하여 표시되는 뷰의 방향 또는 status bar의 방향 또는 스타일을 변경할 수 있습니다.

이 메소드를 override할 경우 특정 시점에 super를 호출해야 합니다.

(view의 bounds는 정의되지만, 방향은 설정되지 않은 상태)

Supporting Accessibility

Note

뷰 컨트롤러가 popover 내부의 뷰 컨트롤러에 의해 보여지는 경우, 보여진 컨트롤러가 해제된 후 이 메소드가 현재 뷰 컨트롤러에서 호출되지 않습니다.

 

viewDidAppear(_:)

뷰 컨트롤러에 view hierarchy에 뷰가 추가되었음을 알립니다.

Parameter

animated: true이면 애니메이션을 사용하여 뷰가 window에 추가된 것

Discussion

이 메소드를 override하여 view presenting과 관련된 추가 task를 수행할 수 있습니다. (ex. 애니메이션 등)

특정 시점에 super를 호출해야 합니다.

Note

뷰 컨트롤러가 popover 내부의 뷰 컨트롤러에 의해 보여지는 경우, 보여진 컨트롤러가 해제된 후 이 메소드가 현재 뷰 컨트롤러에서 호출되지 않습니다.

 

viewWillLayoutSubviews()

뷰가 하위 뷰를 layout하려고 함을 뷰 컨트롤러에 알리기 위해 호출됩니다. (ex. UIView에서 layoutSubvies 메소드가 발생되기 직전, collectionView의 cell이 로드될 때, 가로/세로 방향 변경 시 등)

Discussion

view의 bounds가 변경되면, 하위 뷰의 위치를 조정합니다.

뷰 컨트롤러는 뷰가 하위 뷰를 배치하기 전에 이 메소드를 변경하도록 override할 수 있습니다.

이 메소드의 default implementation은 아무 것도 하지 않습니다.

 

viewDidLayoutSubviews()

뷰 컨트롤러에 뷰가 하위 뷰를 배치했음을 알리기 위해 호출됩니다. (ex. 가로/세로 방향 변경 시 - view의 bounds가 업데이트되거나 view의 layout이 재계산될 때 마다 재호출)

Discussion

뷰 컨트롤러의 뷰에 대한 bounds가 변경되면 뷰는 하위 뷰의 위치를 조정한 다음 시스템이 이 메소드를 호출합니다.

그러나 호출되는 이 메소드는 뷰의 하위 뷰의 개별 레이아웃이 조정되었음을 나타내지 않습니다.

각 하위 뷰는 자체 레이아웃을 조정하는 역할을 합니다. (하위 뷰가 설정되고 크기, 위치, 제약 등이 적용됨)

 

뷰 컨트롤러는 뷰가 하위 뷰를 배치한 후 이 메소드를 변경하도록 override할 수 있습니다.

이 메소드의 default implementation은 아무 것도 하지 않습니다.

 

viewWillDisappear(_:)

뷰 컨트롤러에게 view hierarchy에서 해당 뷰를 제거하려고(사라지려고) 함을 알립니다.

Parameter

animated: true이면 뷰의 소멸이 애니메이션화되고 있는 것입니다.

Discussion

이 메소드는 뷰 계층에서 제거되는 뷰에 대한 응답으로 호출됩니다.

view를 실제로 제거하기 전과 애니메이션을 구성하기 전에 이 메소드를 호출합니다.

 

하위 클래스는 이 메소드를 override하고 변경 사항을 커밋하거나 view의 첫번째 responder status를 resign 하거나 기타 관련 task를 수행하는 데 사용할 수 있습니다.

예를 들어, 이 메소드를 사용하여 view를 처음 표시했을 때 viewDidAppear(_:) 메소드에서 변경한 status의 방향 또는 style로 되돌릴 수 있습니다. (또는 데이터 저장, 네트워크 작업 중지 등)

이 메소드를 override 할 경우 특정 시점에 super를 호출해야 합니다.

 

viewDidDisappear(_:)

view hierarchy에서 뷰가 제거되었음을 뷰 컨트롤러에 알립니다.

Parameter

animated: true이면, 뷰가 사라질 때 animated 되었다는 것

Discussion

이 메소드를 override하여 view의 해제 또는 hidden과 관련된 추가 task를 수행할 수 있습니다.

이 메소드를 override 할 경우 특정 시점에 super를 호출해야 합니다.

 

감사합니다 :)

 

반응형