스토리 보드 사용이 아닌 programatically 하는 법 입니다!
네비게이션 컨트롤러를 사용하기 위해서 보통 뷰 컨트롤러를 루트뷰로 가지게 됩니다.
루트뷰(rootView)가 뭔지 간단히 설명을 드려보면...
NavigationController나 TabBarController는 사실 유저입장에서 어떤 화면의 역할을 하는게 아니지요.
뻥 뚤린 액자 같은거랄까요? 그럼 실제로 내용물 역할을 하는 사진같은 ViewController가 있어야겠죠.
NavigationController나 TabBarController라는 액자에 내용물이 되어주는 ViewController를 RootViewController라 이해하시면 어떨까 싶습니다.
예를 들어 뷰 컨트롤러를 상속받은 FirstViewController라는 클래스가 있다고 쳐 봅시다! 이 클래스를 루트뷰로 하는 네비게이션 컨트롤러를 만들어보겠습니다.
let rvc = FirstViewController()
let nav = UINavigationController(rootViewController: rvc)
짠! 이렇게 간단하게 FirstViewController를 품은 네비게이션 컨트롤러를 만들어 주었습니다.
뷰 컨트롤러를 불러와야 할 때, 이렇게 루트뷰를 포함한 네비게이션 컨트롤러를 상황에 따라 불러와 사용해주시면 됩니다.
그 상황중에 한 예가 오늘 사용해 볼 TabBarController에 넣는 경우라고 할 수 있겠습니다.
UITabBar는 우리가 앱 안에서 자주 보는 하단의 이동 메뉴(?) 입니다.
이 탭 바들은 각각 다른 뷰를 보여주는 역할을 합니다.
탭 바에 들어있는 뷰 들은 독립적, 개별적으로 움직여야 맞겠죠! 그에 따라서 네비게이션 컨트롤러도 따로따로 만들어 줘야 합니다.
그렇게 되면 계층은 이런식이겠죠?
탭바 <- 네비게이션 <- 뷰
뷰는 네비게이션에 들어있고 네비게이션은 탭바에 들어있는!
직관적으로 이렇게 이해하신 내용을 바탕으로 코드를 보겠습니다.
첫번째 탭은 네비게이션이 없는 뷰컨트롤러를, 그 밖의 3개의 탭은 뷰컨트롤러를 품은 네비게이션컨트롤러를 보여주도록 작성이 되어 있지요?
import UIKit
class ExampleTabBarController: UITabBarController, UITabBarControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let tabOne = FirstViewController() // 네비게이션 컨트롤러 없는 뷰컨트롤러
//탭바를 아름답게 꾸며주겠습니다. 타이틀도 넣어주고 이미지도 넣어줍니다.
let tabOneBarItem = UITabBarItem(title: "탭 1", image: UIImage(named: "tab1"), tag: 0)
tabOne.tabBarItem = tabOneBarItem
let tabTwo = UINavigationController(rootViewController: SecondViewController()) // 뷰컨 품은 네비게이션 컨트롤러
let tabTwoBarItem = UITabBarItem(title: "탭 2", image: UIImage(named: "tab2"), tag: 1)
tabTwo.tabBarItem = tabTwoBarItem
let tabThree = UINavigationController(rootViewController: ThirdViewController())
let tabThreeBarItem = UITabBarItem(title: "탭 3", image: UIImage(named: "tab3"), tag: 2)
tabThree.tabBarItem = tabThreeBarItem
let tabFour = UINavigationController(rootViewController: FourthViewController())
let tabFourBarItem = UITabBarItem(title: "탭 4", image: UIImage(named: "tab4"), tag: 3)
tabFour.tabBarItem = tabFourBarItem
//탭바컨트롤러에 뷰 컨트롤러를 array형식으로 넣어주면 탭바가 완성됩니다.
self.viewControllers = [tabOne, tabTwo, tabThree, tabFour]
}
}
이 탭 바 컨트롤러가 앱 자체의 RootView가 된다면 앱 실행시에 탭바가 있는, 일부 탭에는 네비게이션이 포함된 뷰를 보여줄 수 있게 됩니다!
그런데 이런 생각을 할 수가 있어요!
"아니! 난 다르다! 나는 귀차니스트이기 때문에 탭바 자체에 네비게이션 컨트롤러를 달겠어! 그럼 하나만 달면 되잖아!"
이렇게 만들어 보시면 문제를 바로 느끼게 되실텐데요!
탭바 자체가 하나의 뷰로서 네비게이션 컨트롤러를 갖는것이지 않습니까?
예를 들어서,
탭바 이하의 뷰 컨트롤러들이 각기 다른 네비게이션 타이틀을 가져야 한다고 가정해보겠습니다.
그래서 각각 뷰컨트롤러가 최초로 불러와질 때 (ViewDidLoad 시) 타이틀을 "1번뷰", "2번뷰", "3번뷰", "4번뷰"로 만들어줬습니다.
그럼 어떤 일이 일어날까요?
.
.
.
.
.
네 탭을 다 불러오고 나서는 탭 사이를 돌아다니면 마지막으로 ViewDidLoad를 실행시켰을 때 정해준 타이틀이 탭과 상관없이 계속 떠있겠죠. 만약 이걸 고치자고 ViewWillAppear에 넣는다고 쳐 봅시다... 그렇다고 하더라도 화면을 전환할 때 마다 계속 네비게이션을 수정해줘야 시각적으로 문제가 없겠죠
단순 시각적인 문제 뿐 아니라 계층과 화면전환에 있어서도 바람직한 방법이 아니라고 하니 더는 엉뚱해지지 않도록 합시다!
혹시 궁금한 점이 있으시다면 언제든 편하게 댓글을 남겨주세요!
[iOS/Swift] 스택(Stack)과 스택 오버플로우란? 예제로 알아보기 (0) | 2022.02.16 |
---|---|
[Swift] 스위프트의 값 타입과 참조 타입 (코드로 실험하기) (0) | 2022.02.15 |
[iOS/Swift] Navigation Bar에 Search Bar 예쁘게 넣는 법 (2) | 2022.02.11 |
[iOS/Swift] Singleton 패턴 사용의 이유와 사용 방법 (0) | 2022.02.08 |
[iOS/Swift] MKMapKit, CLCoreLocation 으로 지도앱 만들기- 소스코드 제공 (10) | 2022.02.03 |