環境
Swift3, Xcode8.2。
普通の赤いバッジのつけかた
let tabItem: UITabBarItem = self.tabBar.items![0]
tabItem.badgeValue = ""
こだわりがなければこれでデフォルトの赤丸がつく。
今回は任意の画像をバッジとして表示したい。
自分でaddSubview
するしかないっぽい
UITabBar
には気の利いたインターフェイスは用意されていないので、自分でUITabBar
の上に貼り付ける。
**問題は貼り付ける座標の求め方。**ググるとself.tabBar.frame.width...
のようにタブバーの横幅をタブ数で割り、バッジの位置を算出するものが散見されるが、 iPad でのタブは画面中央に寄り気味となるので、ずれる。
今回はUITabBar
のsubViews
のsubViews
からアイコンのview
を取得できたので、そこにaddSubview
した。
できあがりイメージ
アイコンの`view`は`UITabBarSwappableImageView`クラスらしい。非公開なクラスなのでクラス名を指定したりするとリジェクトの対象となるかも。`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)
}
}
}
}