はじめに
とりあえずXcode11対応終わりました。ごりごりDarkModeに対応させるものじゃなくてよかったです。いずれその日がやってくるかもしれませんが、、
タブバー 、バッジ周りiOS13 Xcode11で少し対応したので記します。
背景
自分が担当しているプロダクトではタブバーを使用して状況に応じてアイコンにバッジ表示をしていますが、デフォルトバッジのサイズがちょっと大きいということでサイズ変更できるライブラリを使用していました。
ですがUITabBar周りのView hierarchyがちょっと変わってしまったせいで、バッジが期待の場所に配置されなかったりサイズ感変わったりなどの不具合で出てきてしまって、多くのバッジ系ライブラリにIssue立てられてました。
ライブラリ選定もパッと決めるには気後れするし、無理やり使用してるライブラリに合わせて調整するのもアレなのでバッジ生成する自前Viewを作る方向で動いていました。
が、仮定のいい感じのハックを見つけたのでナレッジとしてあってもいいかなと思ったので記載。
新タブバー階層の変更点
TabBarの旧番、新番の階層は以下のようになっています。
| iOS13未満 | iOS13以上 |
|---|---|
![]() |
![]() |
今まではUITabBarButton > UITabBarSwappableImageViewとなっていて、このUITabBarSwappableImageViewがバッジのアイコンのViewになってます。
なのでおそらく、大抵のライブラリはこのアイコンViewのframe拾ってきてゴニョゴニョしてバッジを配置する座標を出してsubviewに追加、のような感じだったと思いますが、新たにUIVisualEffectViewが間に入ったので座標取得の計算が狂ったんでしょうね。
ちなみに、タブ未選択状態だと上記のようにUIVisualEffectView配下に潜り込んでるんですが、選択状態だと前に出てくるようです。
| 選択状態 |
|---|
![]() |
動的に階層が変わってしまうのでUITabBarButtonを基準にして座標を出した方が良さそうなんですが、そもそも未選択時のUITabBarSwappableImageViewは触れるんでしょうか、、
という感じで自前View作って対応せざるを得なかったんですが、少し条件指定ありますが下記ハックを過程で見つけたので採用しました。
有名なハックなのかもしれないですが。
赤丸小さめデフォルトバッジ
該当者
- バッジサイズとりあえず小さくしたい
- 件数入れたり等のカスタムはしないで赤丸だけ
- 座標はデフォバッジくらいでおk
件数等入れる場合は別途作るしかなさそうです。
コード
デフォルト
だとこんな感じ。
let tabBarItem = tabBarController?.viewControllers?[tabIndex].tabBarItem
tabBarItem.badgeValue = ""
まぁ、でけーっちゃでけーですね。別に大きさなんてええやーんが本音。
小さめバッジ
だとこんな感じ。
let tabBarItem = tabBarController?.viewControllers?[tabIndex].tabBarItem
tabBarItem.badgeValue = "●"
tabBarItem.badgeValue = .clear
tabBarItem.setBadgeTextAttributes([NSAttributedStringKey.foregroundColor.rawValue: UIColor.red], for: .normal)
いい感じのサイズです。
やってることとしては、バッジの色をクリアにしてしまい、ブレッドポイントをバッジとして使用するといった感じ。
色も変えられるので、サイズをざっくり小さくするだけの対応ならこれでいけそう。
終わりに
上記の条件でいいのならだいぶ時間を削減できる。
考える人もいるもんだなぁと感心しました。
参考
https://stackoverflow.com/questions/31337803/how-to-add-small-red-dot-in-uitabbaritem




