1

我的好奇心使我将View类型作为参数传递给@ViewBuilder. 将模型/原始类型作为参数传递@ViewBuilder是完全有效的。

如下代码所示。

struct TestView<Content: View>: View {
    
    let content: (String) -> Content
    
    init(@ViewBuilder content: @escaping (String) -> Content) {
        self.content = content
    }
    
    var body: some View {
        content("Some text")
    }
}

struct ContentTestView: View {
    
    var body: some View {
        TestView {
            Text("\($0)")
        }
    }
}

代替String

let content: (String) -> Content

如果我尝试传递 SwiftUIView类型,那么 Compiler 会对此不满意。

let content: (View) -> Content

即使 params for@ViewBuilder接受自定义协议类型,例如Searchable但不接受View协议。

编译器告诉我这个Protocol 'View' can only be used as a generic constraint because it has Self or associated type requirements

我的整个想法是content可以允许保留Section/List/Text它。

编辑:我希望代码如下。

struct TestView<Content: View>: View {

    let content: (View) -> Content

    init(@ViewBuilder content: @escaping (View) -> Content) {
        self.content = content
    }

    var body: some View {
        content(
            List {
                ForEach(0..<10) { i in
                    Text(\(i))
                }
            }
        )
    }
}

struct ContentTestView: View {

    var body: some View {
        TestView { viewbody -> _ in
            
            Section(header: Text("Header goes here")) {
                viewbody
            }
        }
    }
}

我有什么办法可以做到这一点?

4

1 回答 1

1

可能的解决方案是使用AnyView,例如

struct TestView<Content: View>: View {
    
    let content: (AnyView) -> Content
    
    init(@ViewBuilder content: @escaping (AnyView) -> Content) {
        self.content = content
    }
    
    var body: some View {
        content(AnyView(
            Text("Demo")   // << put here any view hierarchy
        ))
    }
}
于 2020-10-14T11:27:20.033 回答