Edited at

UITabBarにcustomなバッジをつける

More than 1 year has passed since last update.


環境

Swift3, Xcode8.2。


普通の赤いバッジのつけかた

let tabItem: UITabBarItem = self.tabBar.items![0]

tabItem.badgeValue = ""

こだわりがなければこれでデフォルトの赤丸がつく。

今回は任意の画像をバッジとして表示したい。


自分でaddSubviewするしかないっぽい

UITabBarには気の利いたインターフェイスは用意されていないので、自分でUITabBarの上に貼り付ける。

問題は貼り付ける座標の求め方。ググるとself.tabBar.frame.width...のようにタブバーの横幅をタブ数で割り、バッジの位置を算出するものが散見されるが、 iPad でのタブは画面中央に寄り気味となるので、ずれる

今回はUITabBarsubViewssubViewsからアイコンのviewを取得できたので、そこにaddSubviewした。


できあがりイメージ



アイコンのviewUITabBarSwappableImageViewクラスらしい。非公開なクラスなのでクラス名を指定したりするとリジェクトの対象となるかも。UIImageViewにキャストできたので、UIImageViewとして使用した。


コード


CustomBadgeTabController.swift

import UIKit

final class CustomBadgeTabController: UITabBarController {

private enum Tab {
case left
case center
case right

static var allCases: [Tab] {
return [.left, .center, .right]
}
}

private var badges: [UIImageView] = []

override func viewDidLoad() {
super.viewDidLoad()

self.initViewControllers()
self.initBadges()
}

private func initViewControllers() {
let vcs = Tab.allCases.map { tab -> UIViewController in
let vc = UIViewController()
vc.tabBarItem = UITabBarItem(tabBarSystemItem: .search, tag: 0)
return vc
}
self.setViewControllers(vcs, animated: false)
}

// タブバーのバッジを作成
private func initBadges() {
let image = UIImage(named: "Badge")
let size = CGSize(width: 8, height: 8)

// tabBar.subviews.subviewsからアイコンのviewを取得、バッジ貼り付け
self.tabBar.subviews.forEach { tabBarButton in
for subView in tabBarButton.subviews {
guard let icon = subView as? UIImageView else { continue }
let badge = UIImageView(image: image)
// アイコンの右上
badge.frame.origin = CGPoint(x: icon.frame.width - size.width / 2, y: 0)
badge.frame.size = size
icon.addSubview(badge)
self.badges.append(badge)
}
}
}
}