はじめに
ウッ...タイトルが難しい.やりたいことはこうじゃ...
Twitter のこんな感じでセミモーダルを UITabBarController を配置してるときにも表示したいっていう感じ.
今回はセミモーダルを実装するときに私がよく使っている FloatingPanel
を使って実装した時に発生したクラッシュを交えて備忘録的なご紹介ができればと思います.
環境
- Xcode 13.0
- FloatingPanel 2.4.0
準備
プロジェクトは作ったね?いいね.
FloatingPanel はとりあえず Swift Package Manager で追加しておきました.
CocoaPods でも Carthage でも自分が使いたいものを使ってインストールしてください.
SceneDelegate
はとりあえず使わない想定なので削除しておきました.
ちなみに今回使用する UITabBarController は CustomTabBarController
としてサブクラスとして作成しました.
FloatingPanel の使い方は色々あると思うので探してみてください.本体自体の README.md にもめっちゃ詳細に書かれていたりするのでそちらを参照していただければと思います.
UITabBarController に FloatingPanel をつけてみる
純粋に FloatingPanel を UITabBarController につけてみようと思います.
CustomTabBarController.swift
をこんな感じにしてみました.
import FloatingPanel import UIKit final class CustomTabBarController: UITabBarController { private lazy var floatingPanelController: FloatingPanelController = .init(delegate: self) override func viewDidLoad() { super.viewDidLoad() floatingPanelController.addPanel(toParent: self) } } // MARK: - FloatingPanelControllerDelegate extension CustomTabBarController: FloatingPanelControllerDelegate {}
おっと.クラッシュしてしまった...
UITabBarController displays child view controllers with a radio-style selection interface
DeepL に翻訳を任せてみました.(寝てない私は今英語を読める力がありません)
→ UITabBarControllerは、子ビューコントローラをラジオ形式の選択インターフェースで表示します。
UITabBarController の説明だった...
他にも UINavigationController
UISplitViewController
UITableViewController
UICollectionViewController
に FloatingPanel は設定できないらしいです.
解決法を探る
とりあえず雑に検索してみる.「 floatingpanel uitabbarcontroller 」
お,それっぽい Issue だ
UITabBarController
displays child view controllers with a radio-style selection interface. SoFloatingPanelController
doesn't work well when it's added intoUITabBarViewController
directly becauseFloatingPanelController
is a chid view controller of a parent.It's out of control from this library. Please add it to a child view controller(a tab) of
UITabBarViewController
or wrapUITabBarViewController
with a view controller.This sample code can be helpful for you.
https://github.com/SCENEE/FloatingPanel/issues/23#issuecomment-434907953
サンプルコードがリンク切れしてるけど,
Please add it to a child view controller(a tab) of
UITabBarViewController
or wrapUITabBarViewController
with a view controller.
っていうところが肝っぽい.
解決方法
ちょっと補助的に SnapKit を導入してます.
ContainerViewController
を追加しました.
AppDelegate
の UIWindow?
の rootViewController に設定するコードを変更しておきます.
+ window?.rootViewController = ContainerViewController() - window?.rootViewController = CustomTabBarController()
ContainerViewController.swift
はこんな感じで addChild しておきます.
import SnapKit import UIKit final class ContainerViewController: UIViewController { private let customTabBarController: CustomTabBarController = .init() override func viewDidLoad() { super.viewDidLoad() addChild(customTabBarController) view.addSubview(customTabBarController.view) customTabBarController.view.snp.makeConstraints { $0.edges.equalToSuperview() } customTabBarController.didMove(toParent: self) } }
あとは ContainerViewController
側に FloatingPanelController
を設定してあげれば動くはず!!
もろもろ魔改造はしましたがこんな感じに UITabBarController の内側からではなく親から表示させることができました!
今回作成したコードはこちらに
(いい加減, BitBucket は OGP 対応してくれないかな...)
最後に
今回は, Twitter などでよく見られる UITabBarController の上に FloatingPanel を表示する方法を書きました.
これをやったのはたまたま自分が記事内で紹介したクラッシュに遭遇したからっていうのがありました.
ハッピーハロウィーン!!
そういえばハロウィーンでしたね. pic.twitter.com/qq8Jm4fnJp
— 小泉ひやかし🌻 (@nnsnodnb) October 30, 2021
今回はちょっと OGP 作るのサボりました... ぴえん