문제 아닌 문제 상황

뷰 컨트롤러로 화면 전환을 시도해봤다. 역시나 잘 됐지만, 문제 아닌 문제가 발생했다. 뷰 위로 뷰가 딱 겹쳐지지 않고 카드 게임처럼 층이 졌기 때문이다.

이 상황을 묘사하기 어려워서 화면 전환할 수 있는 다른 방법을 찾았고, 내비게이션 컨트롤러를 사용하면 된다는 것을 알았다.

내비게이션 컨트롤러

정의

공식 문서에 따르면, 내비게이션 컨트롤러는 계층적으로 이루어진 컨텐츠 간에 이동할 수 있는 ‘스택 기반’ 방식을 제공하는 뷰 컨트롤러라고 한다.

지금껏 배운 바로는, 뷰 컨트롤러는 하나의 뷰에 대한 동작을 정의했다. 그런데 내비게이션 컨트롤러는 정의만 봐도 ‘계층적인’ 뷰들을 관리하는 듯 하다. 내비게이션 컨트롤러를 단순히 ‘뷰 컨트롤러’라고 하지 않고 ‘컨테이너 뷰 컨트롤러’라고 하는 이유가, 이 뷰 컨테이너들을 모두 담는 의미에서 이렇게 부르는 게 아닐까?

라는 생각과 함께 계속 이 컨트롤러에 대한 개요를 봤는데, 역시 하나 이상의 자식 뷰 컨트롤러를 관리하는 역할을 했다.

방식

내비게이션 뷰 컨트롤러는 화면 전환을 위해 사용될 여러 뷰 컨트롤러들을 가지고 있고, 이들 간의 이동에 사용될 내비게이션 바, 툴바 등을 함께 가지고 있으면서 이 모든 객체들을 크게 묶어 제어한다.

맨 첫번째 화면이 될 루트 뷰를 지정하고, 특정 이벤트가 들어오면(항목 클릭 등) 불러올 화면을 뷰 스택에 쌓아 표현하는 방식으로 진행된다. 스택에 뷰 컨트롤러를 추가하거나 삭제하는 건 세그웨이(segue)를 사용하거나 해당 클래스의 메서드를 사용하면 된다.

뷰를 스택 에 저장하기 때문에, 메서드의 형태 역시 pop, push 와 같은 형태로 되어 있다.

func pushViewController(UIViewController, animated: Bool)
func popViewController(animated: Bool)
func popToRootViewController(animated: Bool) -> [UIViewController]?
func popToViewController(UIViewController, animated: Bool) -> [UIViewController]?

위와 같은 메서드를 사용해서 뷰 컨트롤러를 추가하거나 빼고, 루트 뷰로 이동하거나 특정 뷰로 이동하는 행위를 할 수 있는 것이다.

내비게이션 바

내비게이션 뷰 컨트롤러는 뷰 컨트롤러들을 제어할 뿐만 아니라, 이들을 제어하기 위해 상, 하단에 각각 내비게이션 바와 툴 바를 제공한다.

스토리보드 상에서 내비게이션 컨트롤러를 새로 만들고, 특정 이벤트를 통해 루트 뷰에서 다음 뷰로 넘어가게만 코딩 해 놓으면 넘어간 다음 뷰에서 루트 뷰로 돌아오는 것을 내비게이션 컨트롤러가 자동으로 제공한다. 무엇을 통해? 내비게이션 바를 통해 ..

내 목적은 전환된 뷰가 전환되기 전의 뷰를 완벽하게 덮는 형태로 다른 부가적인 인터페이스는 필요 없었다. 그래서 내비게이션 바나 툴 바가 없이도 내비게이션 컨트롤러로 화면 전환을 할 수 있는지 알아보았다. 그냥 단순히 내비게이션 바를 숨기고(setNavigationBarHidden(Bool, animated: Bool) 메서드 사용)위에 소개한 대로, 상황에 맞게 메서드를 쓰면 됐다.

만약 그런 것 없이 그냥 있는 대로 쓰겠다면, 내비게이션 컨트롤러가 자동적으로 제공하는 내비게이션 바를 씹고 뜯고 맛보고 즐기면 된다. 무려 내용 업데이트도 자동으로 해 준다..!!!

결론(?)

뷰를 딱 겹치게 화면전환 하려면 내비게이션 컨트롤러를 사용하자.

내비게이션 바는 자동으로 pop 기능을 수행하지만, 이게 싫으면 내비게이션 바 숨기고 알아서 메서드 사용하자.

댓글남기기