【SwiftUI】動的に表示するViewを切り替える

画面の一部の View を切り替えるサンプルを作ったので紹介します。ニュースアプリ等でよくあるタブメニューを PickerSegmentedPickerStyle で作成し、タップしたタブごとに表示する View を切り替えます。

struct ContentView: View {
    
    @State private var selectionViewIndex = 0
    
    let views = [
        "1st View",
        "2nd View",
        "3rd View"
    ]
    
    var body: some View {
        VStack {
            Picker(selection: $selectionViewIndex, label: Text("")) {
                ForEach(0..<self.views.count) { index in
                    Text(self.views[index])
                }
            }.pickerStyle(SegmentedPickerStyle())
            Spacer()
            showView()
            Spacer()
        }
    }
    
    private func showView() -> AnyView {
        switch self.selectionViewIndex {
        case 0:
            return AnyView(FirstView())
        case 1:
            return AnyView(SecondView())
        case 2:
            return AnyView(ThirdView())
        default:
            return AnyView(FirstView())
        }
    }
}

showView() の中で Picker の選択インデックスによって表示する View を返しています。返す時は AnyViewキャストしなければなりません。

ちなみに、if 文で分岐するのであれば、以下のように直接 VStack の中に書くことができ、AnyView にキャストする必要もありません。

var body: some View {
        VStack {
            Picker(selection: $selectionViewIndex, label: Text("")) {
                ForEach(0..<self.views.count) { index in
                    Text(self.views[index])
                }
            }.pickerStyle(SegmentedPickerStyle())
            Spacer()
            if self.selectionViewIndex == 0 {
                FirstView()
            } else if selectionViewIndex == 1 {
                SecondView()
            } else if selectionViewIndex == 2 {
                ThirdView()
            } else {
                FirstView()
            }
            Spacer()
        }
    }

switch 文の場合はメソッドに纏めて AnyView として返す形式にしないと以下のエラーが出てしまいます。

Closure containing control flow statement cannot be used with function builder ‘ViewBuilder’

以上

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です