UIViewController 클래스는 일반적인 뷰컨트롤러에서 공유되는 동작들을 정의해놓았다.
개발자들은 아마 거의 UIViewController 클래스를 직접적으로 생성할 일은 거의 없고, 대신에 UIControllerView의 SubClass를 쓰거나, 메소드를 추가하거나, 뷰컨트롤러의 계층을 관리하는데 필요한 프로퍼티등을 추가할 것이다.
뷰컨트롤러의 메인 역할은 하기와 같다 :
뷰 컨트롤러는 거의 혼자 쓰이지 않으며, 대부분 유저 인터페이스의 한 부분을 차지하고있는 여러개의 뷰 컨트롤러를 쓸 것 이다. 예를 들면, 하나의 뷰 컨트롤러는 테이블을 보여주고 있을 수 있고, 다른 뷰 컨트롤러는 그 테이블에서 선택된 아이템을 보여주고 있을 수 있다.
일반적으로 한 번에 하나의 뷰 컨트롤러의 뷰만 볼 수 있다. 뷰 컨트롤러는 새로운 뷰 집합을 표시하기 위해 다른 뷰 컨트롤러를 제공할 수도 있고, 원하는 대로 다른 뷰 컨트롤러의 컨텐츠 및 애니메이션 뷰를 위한 컨테이너 역할을 할 수도 있다.
모든 앱은 최소한 한개의 UIViewController의 subclass를 가지고 있다. 대부분 앱들은 많은 커스텀 뷰 컨트롤러를 포함하고있다. 커스텀 뷰 컨트롤러는 전반적인 앱의 동작에 대해서 정의되어있고, 앱의 외형이나 외형에 대한 상호작용을 포함하고있다. 다음 섹션은 custom subclass의 동작 수행에 대해서 간단하게 살펴볼까 한다.
각각의 뷰컨트롤러는 뷰 계층과, 뷰가 속해있는 클래스의 특성을 저장하고있는 루트 뷰를 관리한다.
루트 뷰는 우선적으로 다른 뷰 계층의 콘테이너 역할을 수행한다. 루트뷰의 위치와 크기는 스스로 소유하고 있는 객체 예를 들면, 부모 뷰나 윈도우 앱에 의해 결정된다.
뷰 컨트롤러는 스스로의 뷰를 Lazy하게 불러온다. 처음 뷰를 로드할 경우 또는 뷰 컨트롤러의 뷰를 만들 때 뷰 속성들에 접근한다. 컨트롤러가 뷰를 구체화 하는 몇 가지 방법에 대해서 말해보자.
상기의 방법들은 마지막엔 결국 같은 결과를 얻게 되는데, 적절한 뷰들의 집합을 만들고, 뷰 속성을 통해 그들을 노출시킨다는 결과를 맞는다.
뷰 컨트롤러의 루트뷰는 항상 할당된 사이즈에 맞게 생성된다. 앱의 뷰 계층에 있는 다른 뷰들은 오토레이아웃에 어디에 위치할지 크기는 어떻게 될지 등의 제약을 주기위해 인터페이스 빌더를 사용한다. 또한 프로그램적으로 이러한 제약을 설정할 수 있고, 이러한 제약들을 적합한 시기에 우리의 뷰에 추가할 수 있다.
시각적으로 뷰가 변할 때, 서브 클래스들이 변화에 반응할 수 있도록 뷰 컨트롤러는 자동적으로 자신이 가지고 있는 메소드들을 실행한다.
viewWillAppear(:) 새로운 뷰가 스크린에 나올 때를 대비하기 위해 사용하라
viewWillDisAppear(:) 뷰가 없어질 때 변화를 저장하거나 상태 정보를 저장하기 위해서 사용하라.
상기의 이미지는 실현 가능한 뷰 컨트롤러의 뷰와 상태 변화를 이미지화한 그림이다. will 콜백이 did 콜백과 쌍을 이루는 것은 아니다. 꼭 알아야 하는 것은 만약 프로세스를 will로 시작했다면, 프로세스를 종료할 때는 will과 did 둘 다 사용해도 된다.
커스텀 UIViewController 서브클래스는 뷰 컨트롤러의 컨테이너의 역할을 할 수 있다. 컨테이너 뷰 컨트롤러는 다른 뷰 컨트롤러가 소유하고 있는 내용들을 보여주는 것을 관리할 수 있다. 차일드 뷰는 있는 그대로 보여질 수 있고 뷰가 소유하고 있는 다른 뷰들과 함께 보여질 수 있습니다. 자연스럽게 이 메소드들은 의미론적으로 내가 만들기에 달려있습니다. 몇개의 하위 뷰들을 뷰 컨트롤러의 계층에 한번에 보여줄 것인지, 칠드런 뷰가 보여질 타이밍, 그리고 뷰컨트롤러 계층의 어디에서 나타날지 결정해야할 필요가 있다. 그리고 뷰 컨트롤러는 칠드런 뷰와 무엇을 어떻게 어떤 관계인지 정의한다. 클린한 퍼블릭 인터페이스를 만드는 것은 프라이빗한 많은 자잘한 디테일에 접근하지 않고도, 칠드런 쪽이 로직적으로 기능을 사용하는 것을 보장한다.
컨테이너 뷰 컨트롤러는 칠드런의 루트뷰를 뷰 계층에 포함시키기 전에 반드시 관계가 되어있어야 한다.
이런 것들은 iOS가 차일드 뷰에게 적절한 이벤트를 라우팅하거나 관리하는 것을 가능하게 한다. 마찬가지로 뷰 계층에서 차일드의 루트뷰를 제거하고 난 뒤에, 스스로를 차일드 뷰 컨트롤러와의 관계를 끊어놔야 한다.
이러한 관계를 끊기 위해서는, 컨테이너는 베이스 클래스에서 정의되어진 특정 메소들을 불러야한다.
이런 메소드들은 클라이언트를 통해서 부르도록 만들어지지 않았으며, 이것은 컨테이너가 해야하는 동작을 구현할 때만 포함시키도록 한다.