본문 바로가기
스파르타코딩 클럽/팀프로젝트

팀프로젝트2 [공유 킥보드 앱 만들기(2) - UITabBarController]

by UDDT 2025. 4. 28.




 팀 프로젝트 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 값을 아무리 늘려줘도 간격이 조정되지 않았다

   디버깅을 위해 뷰 계층을 확인해보니.... 아니나 다를까...

 

     버튼의 영역이 고정되어 있는 것이었다...

  영역이 고정되어 있으니 아무리 간격을 늘려줘도 하단의 영역이 제한되기 때문에 더 밑으로 내려갈 수 없는 것이었다....

 

  따라서 우리는 이미지의 사이즈를 줄이기로 했다....

 

최근댓글

최근글

skin by © 2024 ttuttak