[iOS] TabBarController

Inwoo Hwang·2021년 8월 26일
0

iOS

목록 보기
10/13
post-thumbnail

UITabBarController

Selection에 따라 어떤 child view controller가 화면에 보여질 지 관리하는 Container view controller

탭바 인터페이스는 여러 텝을 window 아래에 두고 선택에 따라 다양한 화면을 제공 해 주는 인터페이스 입니다.

유저가 특정 텝을 선택할 경우 tab bar controller는 그 전에 선택되었던 root view에 구애받지 않고 해당 템에 상응하는 view controller의 root view를 유저에게 보여줍니다. 동일한 텝을 클릭할 때도 동일하게 적용됩니다.

아마 TabBar Controller의 이러한 본질 때문에 당근마켓과 같은 tabBar controller에서도 특정 텝에 해당되는 페이지를 드래그해서 내린 뒤 동일한 텝을 클릭시 다시 드래그가 시작하는 시점으로 돌아가는게 아닌가 싶습니다[막연한 추축. 이 부분은 조금 더 알아보겠습니다.]

텝을 선택함으로써 인터페이스의 컨텐츠를 교체 해 주기 때문에 tabBar 인터페이스가 관리되는 각 텝의 view는 비슷할 필요가 전혀 없습니다. 실제로 tab bar 인터페이스는 다른 타입의 정보 또는 동일한 정보에 대해서 다른 시각적인 표현을 할 때 흔히 사용됩니다.

사용시 주의해야 할 점

tab bar controller의 tab bar view는 절대 다이렉트하게 접근하면 안됩니다.

Tab 설정하기

tab bar controller의 텝을 설정하기 위해서는 각 텝의 root view 가 되는 view controller들을 viewControllers 프로퍼티에 할당해야 합니다.

viewControllers 가 뭘가요?

var viewControllers: [UIViewController]? { get set }

해당 프로퍼티의 디폴트 값은 nil이라고 하네요. tab bar controller를 설정할 때 해당 메서드를 활용하여 각 텝이 어떤 컨텐츠를 보여줘야 하는지 설정이 가능합니다. 해당 배열에 들어가는 순서는 텝 바에 보여지는 순서와 일치하다고 하니 이 순서 또한 tab Bar controller를 구현할 때 굉장히 중요하겠네요. 더 읽어보니 해당 배열에 있는 view controller의 인덱스 순서대로 왼쪽 하단 텝에 보여진다고 합니다. 만약에 텝바에 담아야 하는 viewcontroller의 갯수가 텝바가 뷰에 보여줄 수 있는 범위를 넘어가면 오른쪽 끝에 있는 view controller들은 More navigation controller에 의해 관리된다고 하네요.

viewControllers의 프로퍼티가 runtime시 변경되면 tab bar controller는 변경된 배열로 적용합니다. 그리고 만약 선택되었었던 view controller가 해당 배열에 더 이상 존재하지 않을시 tab item에 해당되는 index에 존재하는 다른 view controller를 선택 해준다고도 공식문서에 적혀있고 만약 이 index 값 또한 잘못된 값이라면 아예 0번째 인덱스에 해당되는 view controller를 화면에 보여준다고 적혀있네요.

Tab 설정하기 [Continue]

다시 텝 설점으로 돌아가서 이 viewControllers 프로퍼티의 설정을 하면서 selectedViewController 프로퍼티 또한 값을 할당 해줘야 한다고 합니다. 이 프로퍼티는 말 그대로 처음에 선택될 viewcontroller를 뜻합니다.

tabBar item과 view controller를 연결시켜주는 작업 또한 잊으면 안됩니다.

*tabBar item은 화면의 tab bar에 보이는 버튼이라 생각하면 편할 것 같습니다

tabBar item과 View Controller들을 연결시켜주기 위해서는

  1. UITabBarItem 클래스의 인스턴스를 생성한 뒤
  2. view controller에게 적합하게 세팅을 하고
  3. 연결 하고자 하는 View Controller의 tabBarItem에 할당 해주어야 합니다.

**위 작업을 하지 않으면 view controller는 그냥 디폴트 tabItem을 생성한다고 하네요. 물론 디폴트 item이기 때문에 어떠한 이미지도 갖고 있지않고 적혀있는 text또한 view controller의 title에 해당되는 겂이 보여진다고 합니다. 이미지를 보여주기 위해서는 tabBar item을 연결 해 주는 작업은 필수인 것 처럼 보입니다. 텝창이 어떤 정보를 담고 있는지 유저가 직관적으로 확인할 방법은 먼저 텝바의 이미지를 확인하는 것일테니 이 연결 작업은 왠만하면 해야하지 않을까 하는게 제 개인적인 생각입니다:)

Tab Bar Controller의 View

UITabBarController 클래스는 UIViewController 를 상속받기 때문에 tab Bar controller또한 자신의 view를 갖고 있습니다. 다만 이 view 프로퍼티는 단지 tab bar view를 담는 container에 지나지 않습니다. tab bar view는 하나 또는 그 이상의 tab bar items을 갖고 있으며 유저에게 텝을 선택할 수 있는 권한을 제공합니다.

자주 쓰이는 Navigation controller 또는 프로그래머가 사용하고자 하는 커스텀 view controller를 tab의 root view controller로 사용할 수 있습니다. 차이점은 navigation controller가 root view controller일 경우 tab bar controller는 navigation에서 보여지는 컨텐츠의 화면 사이즈를 조정해서 tab bar에 가려지지 않게 합니다. 이런 자동 조정이 가능하게 하기 위해서는 tab bar 인터페이스에서 보여지는 모든 view는 autoresizing Mask 프로퍼티를 갖고 있어야 합니다.

State Preservation

iOS 6 이후로는 view Controller의 restorationIdentifier 프로퍼티에게 값을 지정하여 선택된 탭에 해당 되는 view controller가 해당 탭을 참조할 수 있게 된다고 합니다 이 restoration identifier를 생략하게 되면 앱 구성에 대한 상태 보존과 복원 세팅이 초기화 된다고 공식문서를 보고 유추 해 보았습니다[한 번 다시 확인 해 봐야 할 것 같아요]. 무튼 이 restorationIdentifier에게 값을 할당하여서 앱이 중지되기 전에 앱 구성을 기록해서 차후 앱이 시작되었을 때 구성이 복원되어질 수 있게 되니 만역 유저가 작성하다 중지하고 앱을 종료한 시점으로 다시 회귀할 수 있게 한다면 유저의 편의성을 더 올려주니 적절하게 사용하면 좋을 것 같다는 생각이 들었습니다.

실제로 한 번 만들어봅시다!

import UIKit

class CustomTabBarController: UITabBarController {
  
}

먼저 tabBarController를 하나 생성한 뒤 해당 tabBarController의 ViewDidLoad() 메서드 에서 ViewControllers 배열에 들어갈 ViewController를 넣어주시면 됩니다!

override func viewDidLoad() {
        super.viewDidLoad()
        configureTabBar()
        
        viewControllers = [
            createTabBarItem(tabBarTitle: TabBarItems.home.title, tabBarImage: TabBarItems.home.image, viewController: KarrotMarketHomeViewController())
        ]
    }

저 같은 경우 위 메서드를 통해 NavigationController 하나를 만들어서 넣어주었는데요. 해당 메서드는 아래와 같은 세팅을 주었습니다:

private func createTabBarItem(tabBarTitle: String, tabBarImage: String, viewController: UIViewController ) -> UINavigationController {
        
        let navigationController = UINavigationController(rootViewController: viewController)
        navigationController.tabBarItem.title = tabBarTitle
        navigationController.tabBarItem.image = UIImage(named: tabBarImage)
        navigationController.navigationBar.backgroundColor = .white
        navigationController.navigationBar.barTintColor = .white
        navigationController.navigationBar.tintColor = .black
        
        return navigationController
    }

tabBarItem의 title, image와 같은 프로퍼티를 매개변수로 받아 세팅될 수 있게 하였습니다. 또한 제가 만들고자 하는 프로젝트에서 모든 navigationController들의 navigationBar의 색상 설정이 동일하기 때문에 navigation bar 그리고 navigation item의 색상 까지 통일해주었습니다!

UITabBarController | Apple Developer Document

viewControllers | Apple Developer Document

UITabBarItem | Apple Developer Document

Swift. App의 보존과 복원 가이드 - Mjun

profile
james, the enthusiastic developer

0개의 댓글