개발하는 뚝딱이

[iOS] 네비게이션 컨트롤러 Navigation Controller 본문

iOS

[iOS] 네비게이션 컨트롤러 Navigation Controller

개발자뚝딱이 2020. 3. 19. 18:46

네비게이션 인터페이스의 구성요소

네비게이션 컨트롤러의 주요 역할은 컨텐츠 뷰 컨트롤러를 보여주고, 사용자 정의 뷰 (네비게이션 바 또는 툴바) 두 가지를 보여주는 것입니다. 네비게이션 바에서는 뒤로 가기 버튼과 커스터마이징한 버튼을 추가할 수 있으며 옵션으로 툴바 뷰도 제공합니다.  네비게이션 바, 툴 바, 탭 바가 헷갈린다면 다음 링크를 참고해도 좋을 것 같습니다. https://brunch.co.kr/@flatdesign/2

 

 

네비게이션 인터페이스의 객체

네비게이션 컨트롤러는 인터페이스를 구성하기 위해 여러 객체를 사용합니다. 개발자는 컨텐츠를 보여주기 위한 뷰 컨트롤러를 생성하고 네비게이션 바나 탭바는 알아서 생성됩니다. 만약 개발자가 네비게이션 컨트롤러에서 보낸 알람에 응답하고 싶다면, delegate object를 사용해야 합니다.아래 그림은 네비게이션 컨트롤러와 주요 객체의 관계입니다.

네비게이션 컨트롤러에서 네비게이션 바와 툴 바에서 모양과 기능을 바꿀 수 있고 네비게이션 컨트롤러 객체는 스스로 UINavigationBar 객체의 delegate가 될 수 있습니다.

 

개발자는 delegate와 네비게이션 스택에 쌓인 다른 뷰 컨트롤러를 변경할 수 있습니다. 네비게이션 스택은 Last-in, First-out 구조로 네비게이션 컨트롤러에 의해 관리됩니다. 제일 처음 스택에 들어간 아이템이 root view controller가 되며 스택에서 절대 제거되지 않습니다. 가장 마지막에 쌓인 뷰 컨트롤러가 topViewController가 됩니다. 각 뷰들은  UINavigationController 클래스를 통해 추가될 수 있습니다.

 

네비게이션 컨트롤러의 주요 역할은 사용자의 액션에 응답하여, 새 콘텐츠 뷰 컨트롤러를 스택에 쌓거나 스택에서 뷰 컨트롤러를 제거하는 역할을 합니다. 스택의 각 뷰 컨트롤러는 앱의 데이터를 보여주는 역할을 합니다. 예를 들어, 사용자가 현재 보여지는 뷰에서 아이템을 선택하면, 세부정보가 들어있는 뷰 컨트롤러가 스택에 쌓입니다. 사진 앱에서 사진 앨범을 눌렀을 때 앨범을 보여주도록 하는 것처럼 말이죠. 

 

각각의 컨텐츠 뷰 컨트롤러들이 스택의 맨 위에 올라갈 컨벤츠 뷰 컨트롤러를 구성하거나 스택에 쌓습니다. 이 때, 특정 클래스의 객체가 스택에 쌓이는 것에 의존하여 뷰 컨트롤러를 만들지 않도록 해야 합니다. 대신에 스택에서 뷰 컨트롤러가 제거되는 동안 데이터를 다시 가져오려면, 스택에서 더 낮은 뷰 컨트롤러를 위에 있는 뷰 컨트롤러의 delegate로 설정해야 합니다.

 

대부분의 경우, 프로그래밍으로 스택에서 뷰 컨트롤러를 제거할 필요 없습니다. 네비게이션 컨트롤러는 네비게이션 바에서 돌아가기 버튼을 통해 자동으로 최상위 뷰 컨트롤러를 제거할 수 있습니다.

 

 

 

네비게이션 인터페이스 만들기

- 윈도우의 root view controller에 만듦

- 탭 바 인터페이스에서 뷰 컨트롤러의 탭을 만듦

- 다른 뷰 컨트롤러를 모달 형태로 보여주기

 

콘텐츠 뷰 컨트롤러를 정의하기

모든 네비게이션 인터페이스는 한 단계인 루트 단계의 데이터를 갖고 있습니다. 예를 들어, 사진 앱은 데이터 계층에서 루트 단계인 사진 앨범 리스트를 보여줍니다. 사진을 고르면, 선택된 사진은 화면에서 더 크게 보여집니다.

 

네비게이션 인터페이스를 구현하기 위해, 어떤 데이터 계층구조에서 데이터를 어디 배치시킬지 정해야 합니다. 각 레벨에서, 컨텐츠 뷰 컨트롤러는 데이터들을 관리하고 보여주는 역할을 합니다. 만약 다른 레벨에서 보여주는 것이 같다면, 같은 뷰 컨트롤러 클래스의 객체를 여러 개 만들고 각 데이터 집합을 관리하도록 구성할 수 있습니다. 예를 들어, 아래 그림에서 사진 앱은 다른 타입의 데이터를 보여줍니다. 그래서 세 개의 다른 뷰 컨트롤러 클래스가 필요합니다.

 

각 콘텐츠 뷰 컨트롤러는 사용자가 데이터 계층구조의 다른 레벨로 갈 수 있도록 해야합니다. 뷰 컨트롤러가 leaf data(가장 끝)를 관리하는 경우를 제외하곤 말이죠. 아이템의 리스트를 보여주는 뷰 컨트롤러는 테이블 셀에서 탭을 통해 넘어갈 수 있습니다. 

 

스토리보드로 네비게이션 인터페이스 만들기

1. 네비게이션 컨트롤러를 라이브러리에서 드래그하기

2. 인터페이스 빌더로 뷰 컨트롤러를 네비게이션 컨트롤러의 루트 뷰 컨트롤러로 만들기

3. Attributes inspector에서 Initial View Controller의 옵션을 선택하기 (가장 처음 실행될 뷰 컨트롤러)

코딩을 통해 만들기는 다음 링크에서 참조하면 됩니다. 

https://developer.apple.com/library/archive/documentation/WindowsViews/Conceptual/ViewControllerCatalog/Chapters/NavigationControllers.html

 

 

네비게이션 뷰를 위한 풀 스크린 레이아웃

보통, 컨텐츠는 상단의 툴바 혹은 탭바나 하단의 네비게이션 바 사이에 있습니다. 그러나 컨텐츠 뷰는 네비게이션 바, 상태 바, 툴 바를 적절하게 덮어 풀 스크린을 만들 수도 있습니다. 배치는 사용자에게 컨텐츠를 얼마나 보여줄 것인가와 사진 디스플레이나 사용자가 얼마나 더 공간을 원하는지에 따라 바뀝니다. 다음과 같은 요소들에 고려해야 합니다.

 

- 창 (또는 부모 뷰)이 전체 스크린 경계를 채우는 사이즈인가?

- 네비게이션 바는 반투명한가?

- 네비게이션 툴 바가 사용된다면, 반투명인가?

- 뷰 컨트롤러의 wantsFullScreenLayout 속성이 YES인가?

 

위 질문 리스트는 또한 어떤 요소가 먼저 고려해야 할지 보여줍니다. 윈도우 사이즈가 첫 번째 제한 조건입니다. 만약 앱의 메인 창이 (또는 모달식 뷰 컨트롤러의 경우 포함된 부모 뷰) 화면에 걸쳐져 있지 않다면, 해당 뷰 또한 불가능합니다. 마찬가지로, 뷰 컨트롤러가 풀 스크린으로 보여지기 위해서, 네비게이션 바와 툴바가 보이지만 반투명한 것은 문제되지 않습니다. 네비게이션 컨트롤러는 절대로 컨텐츠를 불투명한 네비게이션 바 아래에 두지 않습니다.

 

다음과 같은 순서로 최대 크기의 스크린을 만들 수 있습니다.

1. 커스텀 뷰의 프레임으로 스크린 경계를 지정하기 (자동사이즈 측정 속성 또한 이용하기)

2. 네비게이션 바를 덮을 때, 네비게이션 컨트롤러의 반투명 속성에 YES 선택

3. 툴 바를 덮을 때, 툴바의 반투명 속성에 YES 하기

4. 상태 바를 덮을 때, wantsFullScreenLayout의 속성에 YES 선택

 

사이즈를 UIScreen 클래스의 applicationFrame 속성이 아닌, bounds 속성에 사이즈를 맞춰야 합니다. 네비게이션 컨트롤러는 자동으로 상태바를 포함한 뷰의 사이즈에 적용되기 때문에, 네비게이션 인터페이스에서 모든 상황에서 풀 스크린으로 만드는 것보다 낫습니다.

 

또한 네비게이셔 컨트롤러를 모달로 보여준다면, 컨텐츠는 제한적으로 보여집니다. 뷰 컨트롤러는 상태바를 가리지 않기 때문입니다. 즉, 상위 뷰는 항상 어떻게 모달 창을 보여주는가에 영향을 끼칩니다.

 

 

네비게이션 스택의 상태 변화

뷰 컨트롤러를 스택에서 쌓거나 제거할 때, 네비게이션 컨트롤러는 영향을 받는 뷰 컨트롤러에 메시지를 보냅니다. 스택의 상태가 바뀌었을 때, delegate를 통해 메시지를 또 보냅니다. 아래 그림에서 메시지에 상호응답하는 순서가 잘 나와있습니다. 'New view controller'는 뷰 컨트롤러가 스택의 최상위가 되기 직전에 것을 말합니다.

 

또한 컨텐츠 뷰 컨트롤러간을 조정하기 위해, 네비게이션 컨트롤러의 delegate 메소드를 이용할 수 있습니다. 여러 개의 뷰 컨트롤러를 한 번에 추가하거나 제거할 때, 보여질 뷰만 호출됩니다. 중간 단계의 뷰 컨트롤러 메소드는 콜백에서 일어나는 일이 아니라면, 호출되지 않습니다.

 

isMovingToParentViewController 또는 isMovingFromParentViewController를 이용하여 UIViewController 결과로 뷰 컨트롤러가 나타나거나 사라지는지 확인 가능합니다.

 

 

 

 

출처

https://developer.apple.com/library/archive/documentation/WindowsViews/Conceptual/ViewControllerCatalog/Chapters/NavigationControllers.html

'iOS' 카테고리의 다른 글

[ios/xcode] xcode에서 위치 사용하기  (0) 2020.04.17
[iOS] 델리게이트 Delegate  (0) 2020.04.05
[iOS] View Programming 뷰 프로그래밍  (0) 2020.03.19
[iOS] 앱 시닝(app thinning)  (0) 2020.02.15
[iOS] 에셋 카탈로그  (0) 2020.02.15