LoginSignup
2
3

More than 3 years have passed since last update.

UITabBarController の タブボタンをカスタマイズしてみる

Last updated at Posted at 2019-11-26

0.はじめに

UITabBarController のタブボタンを色々とカスタマイズしたかったので、やってみました。

試してみたのは、以下。

  • タブボタンのサイズを個別に変更する
  • タブボタンの背景色を個別に変更する
  • どのタブも初期選択されない様にしてみる

ということで、どのタブも初期選択されない様にしてみた画像が、こんな感じ。

IMG_3332.PNG

本当は、4つタブがあるんですが、表示されていません。

1.コード

TabBarController.swift
//
//  TabBarController.swift
//  UITableViewController-Sample01
//
//  Created by Kusokamayarou on 2019/11/26.
//  Copyright © 2019 Makurazakiutoya. All rights reserved.
//

import UIKit

class TabBarController: UITabBarController {
    override func viewDidLoad() {
        super.viewDidLoad()
        self.delegate = self
        // 「AutoLayoutをコードから指定する, アニメーションさせながらAutoLayoutを変更する - Qiita」
        // <https://qiita.com/yokurin/items/4932ab488b5b503f2dd5>
        // 「ios - Swift | Adding constraints programmatically - Stack Overflow」
        // <https://stackoverflow.com/questions/26180822/swift-adding-constraints-programmatically>
        let tabBarButtons = self.tabBarButtons()
        // item 1
        tabBarButtons![0].translatesAutoresizingMaskIntoConstraints = false
        self.view.addConstraints([
            NSLayoutConstraint(item: tabBarButtons![0], attribute: .top, relatedBy: .equal,
                toItem: tabBar, attribute: .top, multiplier: 1, constant: 0),
            NSLayoutConstraint(item: tabBarButtons![0], attribute: .bottom, relatedBy: .equal,
                toItem: tabBar, attribute: .bottom, multiplier: 1, constant: 0),
            NSLayoutConstraint(item: tabBarButtons![0], attribute: .left, relatedBy: .equal,
                toItem: tabBar, attribute: .left, multiplier: 1, constant: 0),
            NSLayoutConstraint(item: tabBarButtons![0], attribute: .width, relatedBy: .equal,
                toItem: nil, attribute: .notAnAttribute,  multiplier: 1, constant: 0)
            ])
        // item 2
        tabBarButtons![1].translatesAutoresizingMaskIntoConstraints = false
        self.view.addConstraints([
            NSLayoutConstraint(item: tabBarButtons![1], attribute: .top, relatedBy: .equal,
                toItem: tabBar, attribute: .top, multiplier: 1, constant: 0),
            NSLayoutConstraint(item: tabBarButtons![1], attribute: .bottom, relatedBy: .equal,
                toItem: tabBar, attribute: .bottom, multiplier: 1, constant: 0),
            NSLayoutConstraint(item: tabBarButtons![1], attribute: .left, relatedBy: .equal,
                toItem: tabBarButtons![0], attribute: .right, multiplier: 1, constant: 0),
            NSLayoutConstraint(item: tabBarButtons![1], attribute: .width,  relatedBy: .equal,
                toItem: tabBar, attribute: .width,  multiplier: 0.3333, constant: 0)
            ])
        // item 3
        tabBarButtons![2].translatesAutoresizingMaskIntoConstraints = false
        self.view.addConstraints([
            NSLayoutConstraint(item: tabBarButtons![2], attribute: .top, relatedBy: .equal,
                               toItem: tabBar, attribute: .top, multiplier: 1, constant: 0),
            NSLayoutConstraint(item: tabBarButtons![2], attribute: .bottom, relatedBy: .equal,
                               toItem: tabBar, attribute: .bottom, multiplier: 1, constant: 0),
            NSLayoutConstraint(item: tabBarButtons![2], attribute: .left, relatedBy: .equal,
                               toItem: tabBarButtons![1], attribute: .right, multiplier: 1, constant: 0),
            NSLayoutConstraint(item: tabBarButtons![2], attribute: .right, relatedBy: .equal,
                               toItem: tabBarButtons![3], attribute: .left, multiplier: 1, constant: 0)
            ])
        // item 4
        tabBarButtons![3].translatesAutoresizingMaskIntoConstraints = false
        self.view.addConstraints([
            NSLayoutConstraint(item: tabBarButtons![3], attribute: .top, relatedBy: .equal,
                               toItem: tabBar, attribute: .top, multiplier: 1, constant: 0),
            NSLayoutConstraint(item: tabBarButtons![3], attribute: .bottom, relatedBy: .equal,
                               toItem: tabBar, attribute: .bottom, multiplier: 1, constant: 0),
            NSLayoutConstraint(item: tabBarButtons![3], attribute: .right, relatedBy: .equal,
                               toItem: tabBar, attribute: .right, multiplier: 1, constant: 0),
            NSLayoutConstraint(item: tabBarButtons![3], attribute: .width,  relatedBy: .equal,
                               toItem: tabBar, attribute: .width,  multiplier: 0.3333, constant: 0)
            ])
        // ios - How to definitively set UITabBar background color and UITabBar tint color - Stack Overflow
        // https://stackoverflow.com/questions/37626377/how-to-definitively-set-uitabbar-background-color-and-uitabbar-tint-color
        self.tabBar.barTintColor = .systemBackground
    }
    // 「小ネタ:UITabBarControllerに「モーダル表示するボタン」を追加する(Swift) - Qiita」
    // <https://qiita.com/paming/items/a1413480358fa81728cf>
    override func viewDidLayoutSubviews() {
        let tabBarButtons = self.tabBarButtons()
        UIView.setAnimationsEnabled(false)
        // item 1
        tabBarButtons![0].alpha = 0.0
        tabBarButtons![0].backgroundColor = .red
        tabBarButtons![0].layoutIfNeeded()
        // item 2
        tabBarButtons![1].backgroundColor = .cyan
        tabBarButtons![1].layoutIfNeeded()
        // item 3
        tabBarButtons![2].backgroundColor = .green
        tabBarButtons![2].layoutIfNeeded()
        // item 4
        tabBarButtons![3].backgroundColor = .yellow
        tabBarButtons![3].layoutIfNeeded()
        UIView.setAnimationsEnabled(true)
    }
}

extension TabBarController: UITabBarControllerDelegate {
    // 「swiftでUITabBarの特定のタブをタップした時にモーダル - Qiita」
    // https://qiita.com/higan96/items/5ea742b59a48a34baa32
    internal func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
        self.viewDidLayoutSubviews()
        return true
    }
    // 「[Swift]タブ切り替え時に切り替え先のメソッドを実行する」
    // https://nobuhiroharada.net/2018/04/06/change-tab/
    internal func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
    }
}

// 「Swift - UITabbarControllerにモーダル表示するボタンを追加(68046)|teratail」
// <https://teratail.com/questions/68046>
extension TabBarController {
    func tabBarButtons() -> [UIView]? {
        return self.tabBar.subviews.reduce([], {
            (ret: [UIView], item:AnyObject) -> [UIView] in if let v = item as? UIView {
                if v.isKind(of: NSClassFromString("UITabBarButton")!) {
                    return ret + [v]
                }
            }
            return ret
        })
    }
}
■ タブボタンにアクセスするには?

これが無いと何も変更できません…。

  1. 以下の記事を参考に、tabBarButtons() を作成します。
■ タブボタンのサイズを個別に変更するには?
  1. 以下の記事を参考に、viewDidLoad() で各タブボタンに Constraints を設定します。
■ タブボタンの背景色を個別に変更するには?
  1. 以下の記事を参考に、viewDidLoad() でタブバーの背景色を設定します。
  2. 以下の記事を参考に、viewDidLayoutSubviews() を作成し、初期表示時のタブボタンの背景色を設定します。
  3. 以下の記事を参考に、tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) を作成し、タブ選択時のタブボタンの背景色を設定します。
■ どのタブも初期選択されない様するには?

これまでの設定の応用になります。

  1. 初期選択される左端のタブの幅を0にして、他のタブボタンのサイズをうまいこと調整します。
  2. 背景色の設定と同様のやり方で、alpha 値を 0.0 にして、タブを見えなくします。

99.ハマりポイント

  • 結構ハマったと様に思いますが…、ずいぶん前にやったので覚えてません…。

😭😭😭

XX.まとめ

他にも色々とカスタマイズ出来るかもしれませんね♪

以下、GitHub にも UP してますので、参考になれば♪

🙇‍♂️🙇‍♂️🙇‍♂️

2
3
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3