🐵

Genericsを用いて別のViewにTextやButtonなどのViewを渡す方法

2024/04/12に公開

別のViewにTextButtonなどのViewを渡したい場合は、以下のようにlet content: Viewとしてもエラーが発生し、ビルドができない。Viewは型ではなく、プロトコルであるためプロパティでは利用できない。

struct GenericView: View {
    let content: View //←エラーが発生
    let title: String
    
    var body: some View {
        Text(title)
        content
    }
}

では、どうしたら良いかというとGenericsを用いてViewを渡すようにするといい。

struct GenericView<T: View>: View {
    let content: T
    let title: String
    
    var body: some View {
        Text(title)
        content
    }
}

呼び出しもとは以下のようになる。

struct ContentView: View {
    var body: some View {
        VStack {
            GenericView(content: Text("generic View"), title: "タイトル")
            Text("Hello, World!")
        }
    }
}

ビルド結果

また、クロージャーを渡すこともでき、こちらの方が実務ではよく見かける。
クロージャーで書いてしまった方が効率よく書けるし、可読性が上がるため。

struct GenericView2<T: View>: View {
    let content: () -> T
    let title: String
    
    var body: some View {
        Text(title)
        content()
    }
}

呼び出しもとは以下のようになる。

GenericView2(
    content: {
        VStack {
            Text("generic View")
            Text("generic View2")
            Text("generic View3")
            Text("generic View4")
        }
    }, title: "タイトル"
)

Discussion