iOS) 그래서 ViewController 란 뭘까

2021. 2. 27. 21:13iOS

iOS 특유의 유저 인터페이스 구조부터 파악하고 넘어가보자.

 

iOS는 일반 데스크톱과 UI 표현 구조가 좀 다르다. 핸드폰 특성상 단 하나의 화면만 표현되고, 다른 프로그램이 실행되면 기존의 화면은 내려가고 그 자리를 새로운 화면이 채운다. iOS에서는 이러한 과정을 구현하는데 윈도우와 뷰 객체가 사용된다. 

 

윈도우와 뷰

윈도우는 iOS 에서 디바이스의 스크린을 빈틈없이 채우기 위한 객체로, 항상 UI 표현 계층의 최상위에 위치한다. 뷰의 일종이지만 직접 컨텐츠를 가지지는 않으며 컨텐츠를 가진 뷰 객체를 내부에 배치하여, 화면에 출력하는 역할만을 수행한다. 

 

때문에 화면이 전환되더라도 윈도우 객체는 전환되지 않으며, 내부의 배치된 의 컨텐츠만 바뀐다.

 

뷰는 컨텐츠를 담아 이를 스크린상에 표시하고, 사용자의 입력에 반응한다. 윈도우의 일부를 자신의 영역으로 정의하고, 여기에 필요한 컨텐츠를 채워서 스크린에 나타내는 동시에, 윈도우로부터 전달된 사용자의 입력에 반응하여 그에 맞는 결과를 처리하는 역할이다.

 

하나 이상의 뷰들이 콘텐츠를 표현하면, 윈도우는 모바일 디바이스 스크린에 이것들을 종합하여 표현한다. 이같은 방식으로 다양한 형태의 뷰를 화면에 나타내는데, 영역이 겹쳐질 경우 중첩된 형태로 표현되곤 한다. 아래 그림이 중첩된 인터페이스 구조를 보여주고 있다.

 

 

 

iOS에서 실행되는 모든 애플리케이션은 최소한 하나 이상의 윈도우와 뷰를 가진다. (무조건 윈도우와 뷰를 가지고 있다)

 

대부분의 경우에서 모바일 디바이스 디스플레이는 하나뿐이므로, 애플리케이션이 생성하는 윈도우 역시 하나이지만, 외부 디스플레이가 연결될 경우, 이때는 윈도우가 하나 더 추가된다. (출력모니터 하나당 하나씩 생성된다)

 

윈도우 안에는 뷰, 그것도 수많은 뷰들이 포함되어 있으며, 각각의 뷰는 모두 각자의 영역에서 원하는 내용을 표시한다.

 

윈도우와 뷰 사이는 뷰 컨트롤러를 통해 연결된다. 뷰 컨트롤러는 뷰의 계층을 (view hierarchy) 관리하여, 윈도우에 전달하고, 모바일 디바이스에 감지된 터치 이벤트를 윈도우로부터 전달받아처리하는 역할을 한다.

 

다시말해 윈도우는 뷰 컨트롤러를 통해 제공되는 뷰를 읽어들여 표현할 뿐, 뷰를 직접 관리하는 것이 아니다. 이렇한 특성은 윈도우 객체에 커스텀 코드가 난립하는 것을 방지하며, 앱이 표현해야 하는 모든 뷰를 윈도우 객체 하나가 관리해야 하는 불상사를 막아준다.

 

루트 뷰 컨트롤러

윈도우 객체는 하나의 뷰 컨트롤러를 루트 뷰 컨트롤러로 지정하여 참조한다. 루트 뷰 컨트롤러로 지정되면 스토리보드에서 다음과 같은 화살표가 붙어 루트 뷰 컨트롤러임을 식별해준다.

 

루트 뷰 컨트롤러임을 나타내주는 화살표가 있다

루트 뷰 컨트롤러로 지정되지 못한 나머지 뷰 컨트롤러들은, 루트 뷰 컨트롤러의 관리 대상으로 연결되거나 혹은 다른 방식으로 이어지기도 하지만, 이들은 윈도우 객체의 직접적인 관리 대상이 아니다. 윈도우 대상은 오로지 루트 뷰 컨트롤러만 신경쓰니까.

 

뷰 컨트롤러 View Controller

대부분의 뷰 컨트롤러들은 각자가 하나씩 화면을 담당하여 컨텐츠를 표현하고 뷰를 관리한다. 이를 씬(Scene) 이라는 용어로 부른다. A, B 두개의 씬으로 이루어진 어플리케이션이 있다면 A, B 각각의 씬을 표현할 두 개의 뷰 컨트롤러가 필요하다는 의미로 해석할 수 있다. 씬을 담당하고 콘텐츠를 표시하는 뷰 컨트롤러를 콘텐츠 뷰 컨트롤러라고 한다.

 

하지만 일부 특별한 뷰 컨트롤러는 씬을 표현하는 역할 대신, 다른 뷰 컨트롤러의 연결관계를 관리한다. 이들은 내부에 콘텐츠를 배치하는 대신, 다른 뷰 컨트롤러를 배치하고, 이들을 서로 유기적인 관계로 엮이도록 만든다. 네비게이션 컨트롤러, 혹은 탭바 컨트롤러, 페이지 컨트롤러 등이 대표적인 예다. 이러한 역할을 수행하는 컨트롤러를 컨텐츠 뷰 컨트롤러와 구분하여, 컨테이너 뷰 컨트롤러라고 한다. 컨테이너 뷰 컨트롤러의 일부는 다른 뷰 컨트롤러의 관리를 위해 고유한 역할을 하는 특정 객체를 화면에 부분적으로 추가하는데, 네비게이션 바나 탭 바 등이 이런 목적으로 추가된 객체들이다. 

 

뷰 계층 구조 View Hierarchy

뷰 컨트롤러 내부는 수많은 뷰들로 이루어 지는데, 이들 뷰는 자기 자신을 스크린상에 표시하기도 하지만, 동시에 다른 뷰 객체를 포함하는 컨테이너의 역할도 수행한다. 이를 뷰의 계층 구조(View hierachy)라고 한다. 뷰의 계층 구조 상에서 다른 뷰를 포함하는 뷰는 슈퍼 뷰(super hierachy)가 되고, 슈퍼 뷰에 포함된 뷰는 서브 뷰(subview)가 된다. 하나의 슈퍼 뷰는 다른 슈퍼 뷰의 서브 뷰가 될 수 있으며 서브 뷰 역시 하위에 포함된 서브 뷰를 기준으로 슈퍼 뷰가 될 수 있다.

 

슈퍼 뷰는 서브 뷰가 레이아웃을 구성할 수 있도록 내부적으로 원점을 잡아주는 좌표 체계를 제공한다. 뷰의 계층 구조상에서 뷰들은 서로 상대적인 레이아웃을 이룬다.

 

일반적으로 각각의 씬은 자신만의 뷰 계층 구조를 가지고 있으며, 뷰 계층 구조 최상위에는 하나의 뷰가 존재한다. 이 뷰를 루트 뷰(Root View) 또는 콘텐츠 뷰(Contents View)라고 한다. 테이블 뷰 컨트롤러에서는 테이블 뷰가 루트 뷰이며, 컬렉션 뷰 컨트롤러에선느 컬렉션 뷰가 루트 뷰의 역할을 담당한다. 일반 뷰 컨트롤러에서는 View 객체가 루트 뷰의 역할을 담당한다. 

 

루트 뷰 내부에는 각자의 크기와 영역, 표현할 컨텐츠를 가진 여러개의 서브 뷰가 추가되는데, 일부 뷰는 서로 겹치기도 한다. 루트 뷰는 이러한 서브 뷰들을 모아 하나의 전체 뷰를 구성하고, 뷰 컨트롤러를 통해 이를 윈도우에 전달한다. 

 

 

 

여기까지가 뷰 컨트롤러를 포함한 iOS 핵심 객체들에 대한 설명이다.