SwiftUI:使用可选的内部视图查看

SwiftUI: View with optional inner View

我正在尝试创建一个 SwiftUI 视图,其中可能包含另一个类似这样的视图:

struct EmptyPlaceholderView<Header: View>: View {
    
    let header: Header?
    let text: LocalizedStringKey
    
    init(header: Header? = nil, text: LocalizedStringKey) {
        self.header = header
        self.text = text
    }
    
    var body: some View {
        VStack(spacing: 8) {
            if let header = self.header {
                header
            }
            
            Text(text)
                .scaledFont(.title)
                .foregroundColor(.gray500)
        }
    }
    
}

此代码块编译没有问题,但是当我尝试这样调用此视图时:EmptyPlaceholderView(text: "No Data") 编译器引发以下错误:

Generic parameter 'Header' could not be inferred

我该如何解决这个问题?

您已将您的视图设置为通用类型 Header,因此即使 header 属性 是 nil,您也必须始终指定通用类型。

您可以使用 EmptyView 例如当您不想 Header

EmptyPlaceholderView<EmptyView>(text: "No data")

或者,您可以添加一个新的 init,它只需要一个 text 参数,而不是给 header 一个 nil 默认值。有了这个新 init 的通用类型约束,您将不必再指定 Header 的类型,因为它将被推断为 EmptyView.

init(text: LocalizedStringKey) where Header == EmptyView {
    self.header = nil
    self.text = text
}

init(header: Header?, text: LocalizedStringKey) {
    self.header = header
    self.text = text
}

现在 EmptyPlaceholderView(text: "No data") 可以正常编译并创建 EmptyPlaceholderView<EmptyView>.

对于泛型,在专门化期间应始终指定(显式或推断)类型,因此可能的解决方案是为此使用辅助程序 init,例如

 init(text: LocalizedStringKey) where Header == EmptyView {
    self.init(header: nil, text: text)
 }