앱을 사용하는 사용자에게 매끄러운 화면 전환과 명확한 흐음 제공은 사용자 경험을 크게 좌우하는 중요한 요소다. 이러한 사용자 경험을 구현하기 위해서는 내비게이션 인터페이스에 대한 이해가 필요하다.
iOS의 UIKit은 이를 위해 매우 강력한 내비게이션 시스템을 제공한다.
UINavigationController와 이와 관련된 요소들을 이용하면 사용자에게 자연스러운 화면 전환과 직관적인 인터페이스를 제공할 수 있다.
공식 문서의 설명을 보면 "계층적 콘텐츠를 탐색하기 위한 스택 기반 체계를 정의하는 컨테이너 뷰 컨트롤러" 라고 한다. 좀더 설명을 보면 하나 이상의 자식 뷰 컨트롤러를 관리하는 컨테이너 뷰 컨트롤러 라고 한다.
한 번에 하나의 자식 뷰 컨트롤러만 표시되고 뷰 화면전환 시에 새 뷰 컨트롤러가 화면에 푸시되고 이전 컨트롤러가 숨겨진다고 설명하고 있다.
공식문서에서 제공하는 이미지를 보면 우리가 자주 보던 설정 화면을 볼 수 있다.
게층적 콘텐츠 탐색이란 설명에 대해 어느 정도 이해가 가능하다.
네비게이션 컨트롤러 객체는 네비게이션 스택(Navigation Stack)이라고 하는 정렬된 배열을 사용하여 자식 뷰 컨트롤러를 관리한다. 이 스택은 사용자가 앱 내에서 이동할 수 있는 경로를 정의합니다. 사용자는 이 경로를 따라서 앱의 각 섹션에 이동할 수 있다.
배열의 첫 번째 뷰 컨트롤러는 루트 뷰 컨트롤러(root view controller)이며, 배열의 마지막 뷰 컨트롤러는 스택의 최상위 항목이며 현재 표시 중인 뷰 컨트롤러를 나타낸다. 세그(segue) 또는 메서드를 사용하여 스택에서 뷰 컨트롤러를 추가 및 제거한다. 루트 뷰 컨트롤러는 팝이나 세그를 통해 제거 불가하다.
매서드나 세그를 사용하여 네비게이션 스택의 뷰 컨트롤러를 추가/삭제 가능하다고 하였다. 또는 네비게이션 인터페이스의 뒤로가기(back)버튼을 사용하거나 스와이프를 통해 최상위 뷰 컨트롤러를 삭제하고 아래의 뷰 컨트롤러를 보이도록 할 수 있다.
네비게이션 스택에 새로운 뷰 컨트롤러가 푸시 되면 UIViewController 인스턴스가 생성되고 네비게이션 스택에 추가된다. 위의 설명처럼 최상위 항목이 현재 표시 중인 뷰 컨트롤러가 되기 때문에 추가된 UIViewController가 현재 화면에 보여지게 된다.
네비게이션 스택의 뷰 컨트롤러가 팝 되면 생성되었던 UIViewController의 인스턴스가 다른 곳에서 참조되고 있지 않다면 메모리에서 해제되고, 네비게이션 스택에서 삭제된다. 최상위 뷰 컨트롤러가 현재 화면에 보여지는 뷰 컨트롤러이기 때문에 해당 뷰가 제거되면 네비게이션 스택의 새로운 최상위 뷰 컨트롤러가 다시 화면에 보이게 된다.
// 내비게이션 컨트롤러의 인스턴스를 생성하는 메서드
// 매개변수로 내비게이션 스택의 가장 아래에 있는 루트 뷰 컨트롤러가 될 뷰 컨트롤러를 넘겨준다
init(rootViewController: UIViewController)
// 내비게이션 스택에 있는 최상위 뷰 컨트롤러에 접근하기 위한 프로퍼티
var topViewController: UIViewController?
// 현재 내비게이션 인터페이스에서 보이는 뷰와 관련된 뷰 컨트롤러에 접근하기 위한 프로퍼티.
var visibleViewController: UIViewController?
// 내비게이션 스택에 특정 뷰 컨트롤러에 접근하기 위한 프로퍼티(루트 뷰 컨트롤러의 인덱스는 0)
var viewController: [UIViewController]
// 내비게이션 스택에 뷰 컨트롤러를 푸시
// 푸시 된 뷰 컨트롤러는 최상위 뷰 컨트롤러로 화면에 표시
func pushViewController(UIViewController, animated: Bool)
// 내비게이션 스택에 있는 최상위 뷰 컨트롤러를 팝
// 최상위 뷰 컨트롤러 아래에 있던 뷰 컨트롤러의 콘텐츠가 화면에 표시
func popViewController(animated: Bool) -> UIViewController?
// 내비게이션 스택에서 루트 뷰 컨트롤러를 제외한 모든 뷰 컨트롤러를 팝
// 루트 뷰 컨트롤러가 최상위 뷰 컨트롤러가 된다.
// 삭제된 모든 뷰 컨트롤러의 배열이 반환된다.
func popToRootViewController(animated: Bool) -> [UIViewController]?
// 특정 뷰 컨트롤러가 내비게이션 스택에 최상위 뷰 컨트롤러가 되기 전까지 상위에 있는 뷰 컨트롤러들을 팝
func popToViewController(_ viewController: UIViewController,
animated: Bool) -> [UIViewController]?
선택한 뷰 컨트롤러가 네비게이션 컨트롤러의 루트 뷰 컨트롤러가 되면서 네비게이션 컨트롤러가 생성 됨
보통 내비게이션 컨트롤러가 애플리케이션 윈도우(window)의 루트 뷰로서 역할을 한다면, 내비게이션 컨트롤러를 ‘applicationDidFinishLaunching:’ 메서드에 구현
UINaviagtionController를 통해 앱의 화면전환을 어떻게 관리하는 지에 대해 이해하며 네비게이션 컨트롤러와 관련된 클래스의 주요 메서드와 프로퍼티에 대한 사용법을 알아보았다.
이러한 내용을 통해 사용자 친화적인 화면 전환 및 앱을 설계하고 구현하는데 도움이 될것이다.
참고 - 부스트코스 iOS프로그래밍, 애플 공식 개발문서