はじめに
とりあえず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