
⎮ 팀 프로젝트 2일차
프로젝트를 시작하면서, 하단에 탭하여 화면을 이동해야 하는 UITabBarController가 필요해졌다.
간단하게 UITabBarController를 구현해보자
⎮ UITabBarController
https://developer.apple.com/documentation/uikit/uitabbarcontroller
UITabBarController | Apple Developer Documentation
A container view controller that manages a multiselection interface, where the selection determines which child view controller to display.
developer.apple.com
UITabBarController는 탭 기반 인터페이스를 제공하는 컨테이너 VC.
화면 하단에 탭 바를 표시하고, 탭을 선택하면 각각의 화면(VC)로 전환해주는 Controller이다
UITabBarController는 기본적으로 viewControllers(탭 안에 들어가는 뷰 컨트롤러의 배열)를 가지고 있고,
selectedIndex를 통해 인덱스로 접근할 수도 있다.
⎮ UITabBarController 구현하기
간단하게 TabBar를 구현하기 위해 3개의 View를 만들어보자
//FirstViewController.swift
import Foundation
import UIKit
class FirstViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
}
위와 같은 방법으로 3번째 View까지 만들어준 뒤,
//UnderTabBarController.swift
import Foundation
import UIKit
class UnderTabBarController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
let firstVC = FirstViewController()
let secondVC = SecondViewController()
let thirdVC = ThirdViewController()
viewControllers = [firstVC, secondVC, thirdVC]
// deSelect 이미지와 Selected이미지를 다르게 설정
firstVC.tabBarItem = UITabBarItem(title: "홈", image: .noneSelectHomeIcon, selectedImage: UIImage(named: "selectedHomeIcon"))
secondVC.tabBarItem = UITabBarItem(title: "등록", image: .noneSelectBoardIcon, selectedImage: UIImage(named: "selectedBoardIcon"))
thirdVC.tabBarItem = UITabBarItem(title: "마이페이지", image: .noneSelectMyPageIcon, selectedImage: UIImage(named: "selectedMyPageIcon"))
}
}
SceneDelegate에서 해당 View를 세팅해준다.
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UnderTabBarController()
window.makeKeyAndVisible()
self.window = window
}

그러나 위의 UI 배치는 굉장히 부자연스럽다.
아이콘과 글자가 너무 딱 붙어 있고, 이미지가 지나치게 크다
이를 조정하기 위해 inset을 설정해주었다.
class UnderTabBarController: UITabBarController {
{ ... }
firstVC.tabBarItem.imageInsets = UIEdgeInsets(top: 0, left: 5, bottom: -15, right: 5)
{ ... }
secondVC.tabBarItem.imageInsets = UIEdgeInsets(top: 0, left: 5, bottom: -15, right: 5)
{ ... }
thirdVC.tabBarItem.imageInsets = UIEdgeInsets(top: 0, left: 5, bottom: -15, right: 5)
}

imageInsets를 설정해주니 이미지의 크기는 조정되었고,
이미지가 전체적으로 하단으로 내려온 모습을 확인할 수 있다.
이제 글씨와 이미지의 간격을 조정해주고자 한다.
이를 위해 글씨를 하단으로 내려주는 코드를 작성했다
class UnderTabBarController: UITabBarController {
{ ... }
firstVC.tabBarItem.titlePositionAdjustment = UIOffset(horizontal: 0, vertical: 10)
{ ... }
secondVC.tabBarItem.titlePositionAdjustment = UIOffset(horizontal: 0, vertical: 10)
{ ... }
thirdVC.tabBarItem.titlePositionAdjustment = UIOffset(horizontal: 0, vertical: 10)
}
}

UI의 배치는 잘 된 것 같고,
색상을 커스텀해주기 위해 다음과 같은 코드를 작성했다.
class UnderTabBarController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
{ ... }
self.tabBar.tintColor = .purple
self.tabBar.layer.borderColor = CGColor(red: 106/255, green: 44/255, blue: 112/255, alpha: 0.7)
self.tabBar.layer.borderWidth = 1
self.tabBar.layer.cornerRadius = 20
self.tabBar.backgroundColor = .white
}
폰트의 크기를 변경하기 위해 아래의 코드를 작성해주었다
{ ... }
tabBar.standardAppearance.stackedLayoutAppearance.normal.titleTextAttributes = [
.font: UIFont.systemFont(ofSize: 12),
.foregroundColor: UIColor.gray
]
tabBar.standardAppearance.stackedLayoutAppearance.selected.titleTextAttributes = [
.font: UIFont.systemFont(ofSize: 12),
.foregroundColor: UIColor.purple
]
{ ... }
이번에 작성한 전체코드는 다음과 같다.
// UnderTabBarController.swift
import Foundation
import UIKit
class UnderTabBarController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
let firstVC = FirstViewController()
let secondVC = SecondViewController()
let thirdVC = ThirdViewController()
viewControllers = [firstVC, secondVC, thirdVC]
tabBar.tintColor = .purple
tabBar.backgroundColor = .white
tabBar.standardAppearance.stackedLayoutAppearance.normal.titleTextAttributes = [
.font: UIFont.systemFont(ofSize: 12),
.foregroundColor: UIColor.gray
]
tabBar.standardAppearance.stackedLayoutAppearance.selected.titleTextAttributes = [
.font: UIFont.systemFont(ofSize: 12),
.foregroundColor: UIColor.purple
]
firstVC.tabBarItem = UITabBarItem(title: "홈", image: .noneSelectHomeIcon, selectedImage: UIImage(named: "selectedHomeIcon"))
firstVC.tabBarItem.imageInsets = UIEdgeInsets(top: 0, left: 5, bottom: -15, right: 5)
firstVC.tabBarItem.titlePositionAdjustment = UIOffset(horizontal: 0, vertical: 10)
secondVC.tabBarItem = UITabBarItem(title: "등록", image: .noneSelectBoardIcon, selectedImage: UIImage(named: "selectedBoardIcon"))
secondVC.tabBarItem.imageInsets = UIEdgeInsets(top: 0, left: 5, bottom: -15, right: 5)
secondVC.tabBarItem.titlePositionAdjustment = UIOffset(horizontal: 0, vertical: 10)
thirdVC.tabBarItem = UITabBarItem(title: "마이페이지", image: .noneSelectMyPageIcon, selectedImage: UIImage(named: "selectedMyPageIcon"))
thirdVC.tabBarItem.imageInsets = UIEdgeInsets(top: 0, left: 5, bottom: -15, right: 5)
thirdVC.tabBarItem.titlePositionAdjustment = UIOffset(horizontal: 0, vertical: 10)
}
}
코드가 너무 복잡한 것 같아 함수와 ForEach로 정리했다
import Foundation
import UIKit
class UnderTabBarController: UITabBarController {
let firstVC = FirstViewController()
let secondVC = SecondViewController()
let thirdVC = ThirdViewController()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
configureBarItems()
configureTabBar()
}
// TabBar의 item을 만들어주는 메서드
private func configureBarItems() {
firstVC.tabBarItem = UITabBarItem(title: "홈", image: .noneSelectHomeIcon, selectedImage: UIImage(named: "selectedHomeIcon"))
secondVC.tabBarItem = UITabBarItem(title: "등록", image: .noneSelectBoardIcon, selectedImage: UIImage(named: "selectedBoardIcon"))
thirdVC.tabBarItem = UITabBarItem(title: "마이페이지", image: .noneSelectMyPageIcon, selectedImage: UIImage(named: "selectedMyPageIcon"))
[firstVC, secondVC, thirdVC].forEach {
$0.tabBarItem.imageInsets = UIEdgeInsets(top: 0, left: 5, bottom: -15, right: 5)
$0.tabBarItem.titlePositionAdjustment = UIOffset(horizontal: 0, vertical: 10)
}
// Controller의 viewControllers 속성에 뷰 컨트롤러들을 담아줌(이렇게 안하면 안나옴)
viewControllers = [firstVC, secondVC, thirdVC]
}
// TabBar 컴포넌트들의 속성을 바꿔주는 메서드
private func configureTabBar() {
tabBar.tintColor = .purple
tabBar.backgroundColor = .white
tabBar.standardAppearance.stackedLayoutAppearance.normal.titleTextAttributes = [
.font: UIFont.systemFont(ofSize: 12),
.foregroundColor: UIColor.gray
]
tabBar.standardAppearance.stackedLayoutAppearance.selected.titleTextAttributes = [
.font: UIFont.systemFont(ofSize: 12),
.foregroundColor: UIColor.purple
]
}
}
* 위의 코드에서 tabBar의 Appearance를 변경해주어도 적용이 되지 않는 문제가 있어 하단에 같이 포스팅한다
⎮ tabBar Font 크기 변경 시 생기는 문제
https://developer.apple.com/documentation/uikit/uitabbarappearance
UITabBarAppearance | Apple Developer Documentation
An object for customizing the appearance of a tab bar.
developer.apple.com
UITabBarAppearance를 사용하면, 탭바를 커스터마이징할 수 있다고 하여,
Font의 크기를 변경하고자 했다
tabBar.standardAppearance.stackedLayoutAppearance.normal.titleTextAttributes = [
.font: UIFont.systemFont(ofSize: 12),
.foregroundColor: UIColor.gray
]
tabBar.standardAppearance.stackedLayoutAppearance.selected.titleTextAttributes = [
.font: UIFont.systemFont(ofSize: 12),
.foregroundColor: UIColor.purple
]

그럼에도 폰트크기는 달라지지 않았다
해당 속성이 적용되지 않아 찾아보니, 아래의 코드로 작성해야 적용된다는 포스팅이 있었다.
아래의 코드를 추가해주고 빌드를 해주니 폰트의 크기가 커지긴 했다.
func configureTabBar() {
let appearance = UITabBarAppearance()
tabBar.tintColor = .purple
tabBar.backgroundColor = .white
appearance.stackedLayoutAppearance.normal.titleTextAttributes = [
.font: UIFont.systemFont(ofSize: 12),
.foregroundColor: UIColor.gray
]
appearance.stackedLayoutAppearance.selected.titleTextAttributes = [
.font: UIFont.systemFont(ofSize: 12),
.foregroundColor: UIColor.purple
]
tabBar.standardAppearance = appearance
tabBar.scrollEdgeAppearance = appearance
}

그러나, 이미지에서 볼 수 있듯 텍스트와 아이콘이 너무 가깝게 붙어버렸고,
[firstVC, secondVC, thirdVC].forEach {
$0.tabBarItem.imageInsets = UIEdgeInsets(top: 0, left: 5, bottom: -10, right: 5)
$0.tabBarItem.titlePositionAdjustment = UIOffset(horizontal: 2, vertical: 5)
}
위의 vertical 값을 아무리 늘려줘도 간격이 조정되지 않았다
디버깅을 위해 뷰 계층을 확인해보니.... 아니나 다를까...

버튼의 영역이 고정되어 있는 것이었다...
영역이 고정되어 있으니 아무리 간격을 늘려줘도 하단의 영역이 제한되기 때문에 더 밑으로 내려갈 수 없는 것이었다....
따라서 우리는 이미지의 사이즈를 줄이기로 했다....
'스파르타코딩 클럽 > 팀프로젝트' 카테고리의 다른 글
| 팀프로젝트2 [공유 킥보드 앱 만들기(4) - 네이버 커스텀 마커, 버튼 이벤트] (0) | 2025.05.01 |
|---|---|
| 팀프로젝트2 [공유 킥보드 앱 만들기(3) - CoreLocation, GeoCoding] (1) | 2025.04.29 |
| 팀프로젝트2 [공유 킥보드 앱 만들기(1) - 디자인, 네이버 Maps API] (0) | 2025.04.26 |
| 팀프로젝트1 [주문 앱 만들기(5) - 데이터 바인딩, 앱 아이콘 적용하기, 앱 이름 한글로 바꾸기] (0) | 2025.04.11 |
| 팀프로젝트1 [주문 앱 만들기(4) - 데이터 바인딩] (0) | 2025.04.10 |