Swift에서 UITabBar 크기 조정하기: 세 가지 접근 방법과 디바이스별 최적화

iOS 앱 개발에서 UITabBar의 크기를 조정해야 하는 상황이 종종 발생합니다. 특히 iPhone X 이후의 모델들은 하단 노치(홈 인디케이터) 영역으로 인해 TabBar 크기 관리가 더욱 중요해졌습니다. 이 글에서는 UITabBar의 크기를 조정하는 세 가지 방법과 디바이스별 최적화 방법을 알아보겠습니다.

UITabBar 크기 조정이 필요한 이유

TabBar는 iOS 앱에서 가장 흔히 사용되는 네비게이션 요소 중 하나입니다. 다음과 같은 이유로 TabBar 크기 조정이 필요할 수 있습니다:

  1. 디자인 요구사항: 앱의 디자인 가이드라인에 맞추기 위해
  2. 접근성 향상: 탭 영역을 더 크게 만들어 사용성 개선
  3. 기기별 최적화: iPhone X 이상의 모델에서 홈 인디케이터 영역 고려
  4. 커스텀 UI 요소: 특별한 디자인 요소를 TabBar에 추가할 때

TabBar 크기 조정의 세 가지 방법

1. Interface Builder 사용

Interface Builder에서 직접 TabBar의 크기를 조정하는 방법은 가장 간단하지만, 코드로 동적 조정이 어렵다는 단점이 있습니다. 이 방법은 고정된 크기를 사용할 경우에만 적합합니다.

2. viewWillLayoutSubviews 오버라이드

이 방법은 뷰 컨트롤러의 viewWillLayoutSubviews 메서드를 오버라이드하여 TabBar의 높이를 조정합니다.

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()
    
    // TabBar 높이 조정
    var tabFrame = tabBarController?.tabBar.frame
    tabFrame?.size.height = 100  // 원하는 높이로 설정
    tabFrame?.origin.y = view.frame.size.height - 100
    tabBarController?.tabBar.frame = tabFrame!
}

이 방법의 장점은 뷰가 레이아웃될 때마다 크기가 적용되므로 일관성이 유지된다는 점입니다.

3. UITabBar의 sizeThatFits 오버라이드

UITabBar를 확장하여 sizeThatFits 메서드를 오버라이드하는 방법입니다.

extension UITabBar {
    override open func sizeThatFits(_ size: CGSize) -> CGSize {
        var sizeThatFits = super.sizeThatFits(size)
        sizeThatFits.height = 100  // 원하는 높이로 설정
        return sizeThatFits
    }
}

테스트 결과에 따르면, sizeThatFits 메서드는 앱 실행 초기에 여러 번 호출되고, 이후 탭 이동마다 2번씩 호출됩니다:

HJH_sizeThatFits
HJH_sizeThatFits
... (여러 번 호출)
HJH_viewWillLayoutSubviews()
HJH_sizeThatFits
HJH_viewWillLayoutSubviews()
HJH_sizeThatFits

이러한 호출 패턴을 고려할 때, viewWillLayoutSubviews를 오버라이드하는 방법이 더 효율적이고 안정적입니다.

디바이스별 최적화

TabBar 크기는 디바이스별로 다르게 적용하는 것이 좋습니다. 특히 iPhone X 이상의 모델에서는 홈 인디케이터 영역을 고려해야 합니다.

먼저 현재 디바이스 모델을 확인하는 방법이 필요합니다. StackOverflow의 이 글을 참고하여 디바이스 타입을 확인할 수 있습니다.

다음은 디바이스 타입에 따라 TabBar 높이와 폰트 크기를 조정하는 예제입니다:

// 디바이스 타입에 따른 설정 조정
var tabBarHeight: CGFloat = 49.0  // 기본 높이
var myDefaultFontSize: CGFloat = 26.0  // 기본 폰트 크기

switch UIDevice().type {
    case .iPhoneSE, .iPhone5, .iPhone5S:
        // 작은 디바이스는 기본값 사용
        print("Using default values for small devices")
    case .iPhone6, .iPhone7, .iPhone8, .iPhone6S:
        // 중간 크기 디바이스
        tabBarHeight = 55.0
        myDefaultFontSize += 2
    case .iPhoneX, .iPhoneXS, .iPhoneXSMax, .iPhoneXR, 
         .iPhone11, .iPhone11Pro, .iPhone11ProMax,
         .iPhone12, .iPhone12Pro, .iPhone12ProMax, .iPhone12Mini:
        // 노치가 있는 디바이스
        tabBarHeight = 65.0  // 홈 인디케이터 영역 고려
        myDefaultFontSize += 4
    default:
        break
}

이제 이 값을 viewWillLayoutSubviews 메서드에서 사용할 수 있습니다:

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()
    
    var tabFrame = tabBarController?.tabBar.frame
    tabFrame?.size.height = tabBarHeight
    tabFrame?.origin.y = view.frame.size.height - tabBarHeight
    tabBarController?.tabBar.frame = tabFrame!
    
    // 탭 바 아이템 폰트 크기 설정
    if let items = tabBarController?.tabBar.items {
        for item in items {
            item.setTitleTextAttributes([NSAttributedString.Key.font: UIFont.systemFont(ofSize: myDefaultFontSize)], for: .normal)
        }
    }
}

iPhone X 이상 모델에서의 특별한 고려사항

iPhone X 이상의 모델에서는 하단 노치(홈 인디케이터) 영역 때문에 TabBar 레이아웃에 추가적인 고려가 필요합니다. StackOverflow의 이 질문에서 이 문제에 대한 해결책을 찾을 수 있습니다.

iOS 11 이상에서는 safeAreaInsets을 사용하여 이 문제를 해결할 수 있습니다:

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()
    
    let safeAreaHeight = view.safeAreaInsets.bottom
    var tabFrame = tabBarController?.tabBar.frame
    
    // 기본 탭바 높이 + 안전 영역 높이
    let totalHeight = tabBarHeight + safeAreaHeight
    
    tabFrame?.size.height = totalHeight
    tabFrame?.origin.y = view.frame.size.height - totalHeight
    tabBarController?.tabBar.frame = tabFrame!
}

이 방법을 사용하면 iPhone X 이상의 모델에서도 TabBar가 적절한 위치와 크기로 표시됩니다.

추가 팁: TabBar 커스터마이징

TabBar 크기 조정 외에도 다양한 커스터마이징이 가능합니다:

  1. 배경색 변경: tabBarController?.tabBar.barTintColor = UIColor.white
  2. 선택된 아이템 색상 변경: tabBarController?.tabBar.tintColor = UIColor.blue
  3. 경계선 제거: tabBarController?.tabBar.shadowImage = UIImage() tabBarController?.tabBar.backgroundImage = UIImage()
  4. 탭 아이템 간격 조정: if let items = tabBarController?.tabBar.items { for item in items { item.imageInsets = UIEdgeInsets(top: 6, left: 0, bottom: -6, right: 0) } }

결론

UITabBar 크기 조정은 앱의 디자인과 사용성에 큰 영향을 미칩니다. 세 가지 방법 중 viewWillLayoutSubviews를 오버라이드하는 방법이 가장 안정적이고 효율적입니다. 디바이스별로 최적화하여 모든 iOS 기기에서 일관된 사용자 경험을 제공하는 것이 중요합니다.

특히 iPhone X 이상의 모델에서는 홈 인디케이터 영역을 고려하여 safeAreaInsets를 활용한 레이아웃 조정이 필요합니다. 이러한 방법을 통해 모든 iOS 디바이스에서 최적화된 TabBar를 구현할 수 있습니다.

코멘트

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다