What is UIViewController In Swift?

YongJunCha·2021년 12월 15일
0

swift

목록 보기
13/18
post-thumbnail

Definition

  • UIKit app의 뷰 계층을 관리하는 객체

Declaration

  • @MainActor class UIViewController : UIResponder

OverView

UIViewController 클래스는 일반적인 뷰컨트롤러에서 공유되는 동작들을 정의해놓았다.
개발자들은 아마 거의 UIViewController 클래스를 직접적으로 생성할 일은 거의 없고, 대신에 UIControllerView의 SubClass를 쓰거나, 메소드를 추가하거나, 뷰컨트롤러의 계층을 관리하는데 필요한 프로퍼티등을 추가할 것이다.


뷰컨트롤러의 메인 역할은 하기와 같다 :

  • 뷰의 내용을 업데이트 하는 것, 대부분 내부적인 데이터의 변화에 대응하는 방식이다.
  • 유저와 뷰의 상호작용에 대한 대응.
  • 뷰를 리사이징 하거나, 전박적인 인터페이스의 레이아웃(배치라고 이해하면 편함)을 관리한다.
  • 다른 객체와(*다른 뷰의 컨트롤러와) Coordinating(조정,조직) 한다.

뷰컨트롤러는 자신이 관리하거나 참여하고 있는 뷰 계층과 밀접하게 엮여있다. 구체적으로 뷰 컨트롤러는 UIResponder 객체와 Responser Chain과 ViewController의 root view 그리고 일반적으로 다른뷰에 속해있는 슈퍼뷰들 사이에 삽입되어있다. 만약 뷰컨트롤러의 뷰중 아무것도 이벤트를 처리하지 않는다면 뷰 컨트롤러는 이벤트를 superview 쪽으로 전달하는 방법이 있다.

뷰 컨트롤러는 거의 혼자 쓰이지 않으며, 대부분 유저 인터페이스의 한 부분을 차지하고있는 여러개의 뷰 컨트롤러를 쓸 것 이다. 예를 들면, 하나의 뷰 컨트롤러는 테이블을 보여주고 있을 수 있고, 다른 뷰 컨트롤러는 그 테이블에서 선택된 아이템을 보여주고 있을 수 있다.

일반적으로 한 번에 하나의 뷰 컨트롤러의 뷰만 볼 수 있다. 뷰 컨트롤러는 새로운 뷰 집합을 표시하기 위해 다른 뷰 컨트롤러를 제공할 수도 있고, 원하는 대로 다른 뷰 컨트롤러의 컨텐츠 및 애니메이션 뷰를 위한 컨테이너 역할을 할 수도 있다.

Subclassing Notes

모든 앱은 최소한 한개의 UIViewController의 subclass를 가지고 있다. 대부분 앱들은 많은 커스텀 뷰 컨트롤러를 포함하고있다. 커스텀 뷰 컨트롤러는 전반적인 앱의 동작에 대해서 정의되어있고, 앱의 외형이나 외형에 대한 상호작용을 포함하고있다. 다음 섹션은 custom subclass의 동작 수행에 대해서 간단하게 살펴볼까 한다.

View ManageMent

각각의 뷰컨트롤러는 뷰 계층과, 뷰가 속해있는 클래스의 특성을 저장하고있는 루트 뷰를 관리한다.
루트 뷰는 우선적으로 다른 뷰 계층의 콘테이너 역할을 수행한다. 루트뷰의 위치와 크기는 스스로 소유하고 있는 객체 예를 들면, 부모 뷰나 윈도우 앱에 의해 결정된다.

뷰 컨트롤러는 스스로의 뷰를 Lazy하게 불러온다. 처음 뷰를 로드할 경우 또는 뷰 컨트롤러의 뷰를 만들 때 뷰 속성들에 접근한다. 컨트롤러가 뷰를 구체화 하는 몇 가지 방법에 대해서 말해보자.

  • 뷰 컨트롤러와 우리 앱의 스토리 보드를 구체화 하자, 스토리보드는 뷰를 구체화 할 때 선호되는 방식이다.
    스토리보드와 함께 뷰와 뷰컨트롤러와 뷰의 연결들을 구체화 하자. 또한 뷰 컨트롤러와의 관계를 seagues를 사용하여 구체화 할 수 있다. seagues는 앱의 동작을 조작하는 것을 훨씬 쉽게 만들어 줄 것이다.

  • Nib file을 사용해서 뷰를 구체화해도 된다. Nib file은 하나의 뷰 컨트롤러에 여러개의 뷰들을 구체화 하는 가능하게 해준다. 그렇지만 뷰 컨트롤러와 seagues로 연결되거나 관계가 맺어질 순 없다. Nib file은 뷰 컨트롤러의 아주 최소한의 정보만을 저장한다.

  • loadView() 메소드를 사용해서 뷰를 구체화 할 수 있다. 이 메소드는 뷰의 계층을 프로그램적으로 그리고 컨트롤러의 뷰 속성 계층을 루트 뷰에 할당해준다.

상기의 방법들은 마지막엔 결국 같은 결과를 얻게 되는데, 적절한 뷰들의 집합을 만들고, 뷰 속성을 통해 그들을 노출시킨다는 결과를 맞는다.

important

  • 뷰 컨트롤러는 자신이 만든 뷰와 모든 그들이 가지고 있는 서브뷰들의 단 하나의 소유자이다. 뷰 컨트롤러는 이런 뷰들을 만들고 그리고 뷰 컨트롤러 스스로가 뷰를 릴리즈 했을 경우와 같은 적절한 시기에 그들에 대한 소유권을 포기해야하는 역할이 있다. 만약 스토리보드 또는 닙 파일을 뷰 객체를 저장하기 위해서 사용했다면, 뷰 컨트롤러가 요청할 때 각 뷰 컨트롤러 객체는 스토리보드나 Nib로 생성한 뷰들의 복사본을 갖게된다. 그러나 만약 뷰를 수동적으로 생성했다면 (Make UI programmatically) 각 뷰 컨트롤러는 반드시 스스로의 유니크한 뷰의 집합을 가지고 있어야한다. 뷰는 뷰 컨트롤러간 공유가 불가능하다.

뷰 컨트롤러의 루트뷰는 항상 할당된 사이즈에 맞게 생성된다. 앱의 뷰 계층에 있는 다른 뷰들은 오토레이아웃에 어디에 위치할지 크기는 어떻게 될지 등의 제약을 주기위해 인터페이스 빌더를 사용한다. 또한 프로그램적으로 이러한 제약을 설정할 수 있고, 이러한 제약들을 적합한 시기에 우리의 뷰에 추가할 수 있다.

시각적으로 뷰가 변할 때, 서브 클래스들이 변화에 반응할 수 있도록 뷰 컨트롤러는 자동적으로 자신이 가지고 있는 메소드들을 실행한다.
viewWillAppear(:) 새로운 뷰가 스크린에 나올 때를 대비하기 위해 사용하라
viewWillDisAppear(
:) 뷰가 없어질 때 변화를 저장하거나 상태 정보를 저장하기 위해서 사용하라.


상기의 이미지는 실현 가능한 뷰 컨트롤러의 뷰와 상태 변화를 이미지화한 그림이다. will 콜백이 did 콜백과 쌍을 이루는 것은 아니다. 꼭 알아야 하는 것은 만약 프로세스를 will로 시작했다면, 프로세스를 종료할 때는 will과 did 둘 다 사용해도 된다.

Implementing

커스텀 UIViewController 서브클래스는 뷰 컨트롤러의 컨테이너의 역할을 할 수 있다. 컨테이너 뷰 컨트롤러는 다른 뷰 컨트롤러가 소유하고 있는 내용들을 보여주는 것을 관리할 수 있다. 차일드 뷰는 있는 그대로 보여질 수 있고 뷰가 소유하고 있는 다른 뷰들과 함께 보여질 수 있습니다. 자연스럽게 이 메소드들은 의미론적으로 내가 만들기에 달려있습니다. 몇개의 하위 뷰들을 뷰 컨트롤러의 계층에 한번에 보여줄 것인지, 칠드런 뷰가 보여질 타이밍, 그리고 뷰컨트롤러 계층의 어디에서 나타날지 결정해야할 필요가 있다. 그리고 뷰 컨트롤러는 칠드런 뷰와 무엇을 어떻게 어떤 관계인지 정의한다. 클린한 퍼블릭 인터페이스를 만드는 것은 프라이빗한 많은 자잘한 디테일에 접근하지 않고도, 칠드런 쪽이 로직적으로 기능을 사용하는 것을 보장한다.

컨테이너 뷰 컨트롤러는 칠드런의 루트뷰를 뷰 계층에 포함시키기 전에 반드시 관계가 되어있어야 한다.
이런 것들은 iOS가 차일드 뷰에게 적절한 이벤트를 라우팅하거나 관리하는 것을 가능하게 한다. 마찬가지로 뷰 계층에서 차일드의 루트뷰를 제거하고 난 뒤에, 스스로를 차일드 뷰 컨트롤러와의 관계를 끊어놔야 한다.
이러한 관계를 끊기 위해서는, 컨테이너는 베이스 클래스에서 정의되어진 특정 메소들을 불러야한다.
이런 메소드들은 클라이언트를 통해서 부르도록 만들어지지 않았으며, 이것은 컨테이너가 해야하는 동작을 구현할 때만 포함시키도록 한다.

  • addChild(_:)
  • removeFromParent()
  • willMove(toParent:)
  • didMove(toParent:)

Conclusion

  • 프로젝트를 진행하다보면 너무 당연하게 뷰컨트롤러를 쓰는데
  • 뷰 컨트롤러의 정의와 동작을 알고 지나가고 싶었다.
  • UIKit app의 뷰 계층을 관리하는 객체
  • 뷰 컨트롤러는 자신이 만든 뷰와 모든 그들이 가지고 있는 서브뷰들의 단 하나의 소유자이다.
  • 기능과 배치, 유저와의 상호작용들을 컨트롤한다.
  • 영어 공부를 할 겸 공식 문서를 번역해봤다.

0개의 댓글