[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를 사용한다.)

Read more

워드프레스에서 고스트로 이전

워드프레스에서 고스트로 이전

이 글을 쓰면서도 믿기 힘든 사실인데, 블로그라는 걸 처음 시작한지가 20년이 되었습니다. 이글루스에서 처음 시작했다가, SK컴즈가 인수한다고 발표함과 동시에 워드프레스로 플랫폼을 옮겼죠. 워드프레스오 옮긴 이후에는 호스팅 환경을 이리 저리 옮기긴 했지만 거의 18년 가까이 워드프레스를 사용해온 것 같습니다. 그 동안 워드프레스는 블로깅 툴에서 명실상부한 범용CMS로 발전했습니다. 사실 웬만한 홈페이지들은 이제

By sooop
띄어쓰기에 대한 생각

띄어쓰기에 대한 생각

업무 메일을 쓸 때 가장 많이 쓰는 말 중에 하나가 메일 말미에 ‘업무에 참고 부탁 드립니다.‘인데요, 어느 날부터 아웃룩에서 이 ‘부탁 드립니다’가 틀렸다고 맞춤법 지적을 하기 시작했습니다. 맞는 말은 ‘부탁드립니다’라고 붙여 쓰는 거라고. 사실 아래아한글 시절부터 이전의 MS워드까지, 워드프로세서들의 한국어 맞춤법 검사 실력은 거의 있으나 마나 한

By sooop

구글 포토에서 아이클라우드로 탈출한 후기

한 때 구글 포토가 백업 용량을 무제한으로 제공해 주겠다고해서, 구글 포토를 사용해서 사진을 백업해왔습니다. 물론 이 이야기의 결말은 저나 이 글을 읽고 있는 여러분이나 모두 알고 있습니다. 사실 AI에게 학습 시킬 이미지 데이터를 모으기 위한 것일 뿐이라거나 하는 이야기는 그 당시에도 있었습니다만, 에이 그래도 구글인데 용량은 넉넉하게 주겠지…하는 순진한

By sooop

Julia의 함수 사용팁

연산자의 함수적 표기 Julia의 연산자는 기본적으로 함수이며, 함수 호출 표기와 같은 방식으로 호출하는 것이 가능합니다. 또한 그 자체로 함수이기 때문에 filter(), map() 과 같이 함수를 인자로 받는 함수에도 연산자를 그대로 적용하는 것이 가능합니다. 특히 + 연산자는 sum() 함수와 같이 여러 인자를 받아 인자들의 합을 구할 수 있습니다. 2 + 3 # = 5 +(2,

By sooop