👻

[SwiftUI] ホーム画面に戻るとボトムバーが消える

2021/08/30に公開

事象

SwiftUIである画面内に .toolbar { ToolbarItem(placement: .bottomBar) { }} でボトムバーを設置していたのだが、なぜかホーム画面に戻るとボトムバーが消えるという事象が発生していた。

原因

↓にあるように、NavigationLinkList の中にあると、ボトムバーが消えるというバグがあるらしい。(詳細な原因は不明)
https://stackoverflow.com/questions/65126986/swiftui-bottombar-toolbar-disappears-when-going-back

対処法

上記記事の回答にあるように、.id を使って強制的にリフレッシュさせるという方法があるらしい。ただ自分の環境だとうまくいかなかったため、最終的に以下のように対処した。(SwiftUI強者に教えてもらった)

同じようなことが起きている人もいた → https://qiita.com/r0227n/items/1e938797b5c80191c739

struct HogeView {
    @Environment(\.scenePhase) var scenePhase
    @State var refreshID = UUID()

    var body: some View {
    List(selection: self.$viewModel.selection) {
            Section {
                ForEach(0..<10, id: \.self) { i in
		// 省略
                }
            }
        }
    }
    .id(self.refreshID)
    .toolbar { self.toolbar }
    .onChange(of: self.scenePhase) { _ in
            DispatchQueue.main.async {
                self.refreshID = UUID()
        }
    }
}

ざっくり解説

まずは @Environment(\.scenePhase) var scenePhase を追加することで、アプリの状態(バックグラウンド, フォアグラウンド など) を監視できるようにする。その上で、これらに変化があった際に
onChangeUUID を更新する。ただそれだけでは変化しないため、 DispatchQueue.main.async で処理を遅らせる。

参考資料

Discussion