[iOS 앱 만들기 005] 뷰 컨트롤러의 종류

iOS앱을 만들 때, 가장 많이 작성하고 다루는 클래스 중의 하나가 뷰 컨트롤러(UIViewController)일 것이다. 그리고 거의 십중팔구 이 기본 클래스를 서브 클래싱하여 커스터마이징한 뷰 컨트롤러를 사용하게된다. 물론 이러한 커스텀 뷰 컨트롤러만 사용해서 전체 앱을 만드는 것도 가능한데, 코코아터치에는 보다 유용한 몇가지 확장된 뷰 컨트롤러들이 존재하고, 이들을 잘 활용하면 전체적으로 작성해야 하는 코드의 양을 크게 줄일 수 있다. (그리고 무엇보다 잘 구현되어 있다.)

뷰 컨트롤러의 종류는 생각보다 많다. 게다가 이 많은 뷰 컨트롤러들 중 대부분은 일상적으로 많이 쓰이는 것들이다. 자세히 설명해 나가면 너무 양이 많으므로, 간략하게 소개만하고 보다 자세한 내용에 대해서는 애플의 공식 개발 문서 중 View Controller Catalog for iOS를 참고하도록 한다. 각각의 뷰 컨트롤러의 사용법은 필요할 때 다시 개별적으로 포스팅하기로 한다.

특화된 뷰 컨트롤러의 종류

기본적인 뷰 컨트롤러의 역할은 뷰를 제어하는 것이지만, 뷰 컨트롤러는 ‘자식 뷰 컨트롤러`를 소유할 수 있는 능력이 있다. (이는 뷰의 서브 뷰가 별도로 뷰 컨트롤러를 가지고 있는 것과는 사뭇 다른 개념이다. 여기서는 뷰 컨트롤러 내에 뷰 컨트롤러가 있는 개념으로, 이런 뷰 컨트롤러들을 특별히 컨테이너 컨트롤러라고 한다.)

  • 네비게이션 컨트롤러(UINavigationController)
  • 탭 바 컨트롤러(UITabBarController)
  • 테이블 뷰 컨트롤러(UITableViewController) – 컨테이너는 아니지만.
  • 페이지 뷰 컨트롤러(UIPageViewController)
  • 스필릿뷰 컨트롤러(UISplitViewController)
  • 팝오버 컨트롤러(UIPopoverController)
  • 그리고 이상의 컨트롤러들의 조합

네비게이션 컨트롤러

네비게이션 컨트롤러는 뷰 컨트롤러 사이를 계층구조로 탐색할 수 있게 해주는 객체이다. 아이폰의 메일 앱에서 보면 메일 상자 목록에서 메일 목록으로 이동한 후 다시 메일 본문을 보는 뷰로 이동하며 depth간 이동을 하게 되는데 이러한 기능은 네비게이션 컨트롤러에 의해 간단히 구현된다. 네비게이션 컨트롤러는 UI 상으로는 네비게이션 바와 하단 툴바(하단 툴바는 있는 경우도 있고 없는 경우도 있음) 그리고 자식 뷰 컨트롤러로 구성된다.

네비게이션 컨트롤러의 자식 뷰 컨트롤러들은 일종의 스택처럼 관리되는데, 맨 처음 표시되는 뷰의 컨트롤러를 rootViewController라고 하고, 세부 항목으로 들어갈 때마다 다음 레벨의 뷰 컨트롤러를 push하고, 반대방향으로 빠져나올 때는 pop하게 된다. 즉 네비게이션 컨트롤러에서 화면에 표시되는 뷰는 스택의 top에 해당하는 뷰 컨트롤러의 뷰가 된다.

통상 앱 델리게이트의 런칭 후 초기화를 담당하는 -application:didFinishLaunchingWithOptions:에서 생성하여 윈도 객체에 설치된다.

    -(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
    {
        _window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
        [_window setBackgroundColor:[UIColor whiteColor]];
        MYRootViewController *_rootViewController = [[MYRootViewController alloc] initWithNibName:@"MYRootViewController" bundle:nil];
        UINavigationController *_navigationController = [[UINavigationController alloc] initWithRootViewController:_rootViewController];
        [_window setRootViewController:_navigationController];
        [_window makeKeyAndVisible];
        return YES;
    }

탭 바 컨트롤러

탭 바 컨트롤러는 네비게이션 컨트롤러와 일견 유사해보이지만, 탭 바 컨트롤러의 서브 뷰 컨트롤러들은 계층 구조가 아닌 수평적인 관계에 있다. 탭바 컨트롤러는 화면 하단에 탭바 UI를 제공하고, 각각의 탭에 대해 뷰 컨트롤러를 선택하게 된다. 또한 별도의 델리게이트를 가질 수 있다. 탭바에 대한 자세한 설명은 다음 자료들을 참고할 것.

테이블 뷰 컨트롤러

테이블 뷰 컨트롤러는 테이블뷰의 델리게이트와 데이터 소스 역할을 함께 담당하도록 특화된 컨트롤러인데, 특화는 특화인데, 사실 두 개의 프로토콜만 따르도록하면 쉽게 만들 수 있다. 테이블 뷰에 대해서는 나중에 이야기할 기회가 있을 것이다.

테이블 뷰 컨트롤러 클래스 레퍼런스

페이지 뷰 컨트롤러

페이지 뷰 컨트롤러는 마치 책장을 넘기듯이 뷰를 보여주는 일종의 컨테이너 컨트롤러이다. 각각의 페이지에 해당하는 뷰 컨트롤러들을 소유하여 책장을 넘기는 효과로 뷰 전환을 해준다. 페이지 뷰 컨트롤러의 인터페이스는 데이터소스 객체와 델리게이트 그리고 제스쳐인식자(Gesture Recognizer)등으로 구성된다.

분할 뷰 컨트롤러(Split View Controller)

분할 뷰 컨트롤러는 아이패드를 위한 컨트롤러로, 설정 앱과 같이 화면을 좌/우 칼럼으로 나눠 왼쪽의 메뉴에서 선택한 항목의 디테일이 오른쪽 칼럼에 나오도록 하는 것이다. 이때 앱은 아이패드가 세로로 세워졌을 때에는 메인뷰(왼쪽 칼럼)를 가려서 팝오버 형태로 사용하도록 해야 한다.

팝오버

팝오버 자체는 뷰 컨트롤러가 아니지만, 분할 뷰를 사용한다면 팝오버의 사용은 필연적으로 따라다니게 되어 있다.

뷰 컨트롤러의 조합

이러한 컨테이너 뷰 컨트롤러는 다른 뷰 컨트롤러를 포함할 수 있는데, 이를 사용하여 네비게이션 계층 구조를 설계할 수 있다. 예를 들어 탭 바를 통해 크게 3~4개의 분류를 만들고, 각각의 탭은 네비게이션 컨트롤러를 할당해서 각각의 탭 마다 다시 하위 구조를 탐색할 수 있는 앱을 만들 수 있다. (사실 기능을 많이 가지고 있는 여러 앱들이 이러한 조합 방식의 UI를 사용한다.)