今回の記事では、次のようにTabBarをカスタマイズしました。
1. UITabBarを継承した、カスタムViewを作成する
2. TabBarItemの配色をUITabBarItemAppearanceで作成する
3. UITabBarAppearanceを生成する
4. UITabBarにセットする
5. UITabBarViewControllerにて、カスタムViewを使う
UITabBarを継承した、カスタムViewは次になります。
final class MyUITabBar: UITabBar { override init(frame: CGRect) { super.init(frame: frame) setupView() } required init?(coder: NSCoder) { super.init(coder: coder) setupView() } private enum Const{ static let backgroundColor: UIColor = .systemGroupedBackground static let tintColor: UIColor = .gray static let selectedColor: UIColor = .black } private func setupView() { let tabBarItemAppearance = setupTabBarItemAppearance() let appearance = UITabBarAppearance() appearance.configureWithOpaqueBackground() appearance.backgroundColor = Const.backgroundColor appearance.stackedLayoutAppearance = tabBarItemAppearance appearance.inlineLayoutAppearance = tabBarItemAppearance appearance.compactInlineLayoutAppearance = tabBarItemAppearance standardAppearance = appearance // iOS15: we need to set scrollEdgeAppearance = appearance } private func setupTabBarItemAppearance() -> UITabBarItemAppearance { let tabBarItemAppearance = UITabBarItemAppearance() // for normal tabBarItemAppearance.normal.iconColor = Const.tintColor tabBarItemAppearance.normal.titleTextAttributes = [NSAttributedString.Key.foregroundColor: Const.tintColor] // for selected tabBarItemAppearance.selected.iconColor = Const.selectedColor tabBarItemAppearance.selected.titleTextAttributes = [NSAttributedString.Key.foregroundColor: Const.selectedColor] return tabBarItemAppearance } }
UITabBarControllerの子となる各ViewControllerでは、次のようにtabBarItemを指定するのみです。
tabBarItemと配色をするAppearanceをコード上で分け、責務が分離できるので非常に見やすいコードとなりました。
final class FirstViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() setupTabBar() } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) } private func setupTabBar() { tabBarItem = UITabBarItem(title: "Home", image: UIImage(systemName: "house"), selectedImage: UIImage(systemName: "house")) } } final class SecondViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() setupTabBar() } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) } private func setupTabBar() { tabBarItem = UITabBarItem(title: "Trash", image: UIImage(systemName: "trash"), selectedImage: UIImage(systemName: "trash")) } }