SwiftUI -我可以为通用视图定义一个空的初始化器吗?

y0u0uwnf  于 2023-08-02  发布在  Swift
关注(0)|答案(3)|浏览(104)

我有一个带有可选@ViewBuilder的通用视图。我想有两个初始化器,一个负责设置@ViewBuilder,另一个应该作为空默认值。

struct OptionalViewBuilder<Content: View>: View {
    
    let content: (() -> Content)?
    
    init(@ViewBuilder content: @escaping () -> Content) {
        self.content = content
    }
    
    init() {
        self.content = nil
    }
    
    var body: some View {
        VStack {
            Text("Headline")
            Divider()
            content?()
        }
    }
}

字符串
如果我用ViewBuilder参数初始化视图,它当然可以工作。然而,当我使用空初始化器时,我得到错误消息:
无法推断泛型参数“Content”

struct ContentView: View {
    var body: some View {
        OptionalViewBuilder {
            Text("Text1")
            Text("Text2")
        }
        OptionalViewBuilder() // <-- Generic parameter 'Content' could not be inferred
    }
}


我知道Swift在运行时需要显式的类型,但是有没有办法让默认的初始化器工作呢?

nfg76nw0

nfg76nw01#

因为OptionalViewBuilder相对于其Content类型是泛型的,所以在默认情况下需要将该类型定义为 something。如果你不想渲染任何东西,它可以是EmptyView
要做到这一点,你需要一个init,它被限制为Content == EmptyView,并且content属性不需要是可选的:

struct OptionalViewBuilder<Content: View>: View {
    
    let content: () -> Content
    
    init(@ViewBuilder content: @escaping () -> Content) {
        self.content = content
    }
    
    init() where Content == EmptyView {
        self.init(content: { EmptyView() })
    }
    
    var body: some View {
        VStack {
            Text("Headline")
            Divider()
            content()
        }
    }
}

字符串

of1yzvn4

of1yzvn42#

我可以通过添加一个空闭包来消除编译错误,像这样:

struct ContentView: View {
    var body: some View {
        OptionalViewBuilder {
            Text("Text1")
            Text("Text2")
        }
        OptionalViewBuilder() {} // I added an empty closure
    }
}

字符串
这能满足你的要求吗

3zwtqj6y

3zwtqj6y3#

也可以将EmptyView()作为默认参数传递

struct OptionalViewBuilder<Content: View>: View {
    
   let content: () -> Content?

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

字符串

相关问题