I'm trying to create a SwiftUI view that may contain another view like this:
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)
}
}
}
this block of code compiles without problems, but when i try to call this view like this: EmptyPlaceholderView(text: "No Data") the compiler fires the following error:
Generic parameter 'Header' could not be inferred
how can I solve this issue ?
CodePudding user response:
You've made your view generic over Header, so even if the header property is nil, you must always specify the generic type.
You can use EmptyView for instance when you don't want to have a Header
EmptyPlaceholderView<EmptyView>(text: "No data")
Alternatively, you can add a new init which only takes a text parameter rather than giving header a nil default value. With generic type constraints on this new init, you won't have to specify the type of Header anymore, since it will be inferred as EmptyView.
init(text: LocalizedStringKey) where Header == EmptyView {
self.header = nil
self.text = text
}
init(header: Header?, text: LocalizedStringKey) {
self.header = header
self.text = text
}
Now EmptyPlaceholderView(text: "No data") compiles fine and creates a EmptyPlaceholderView<EmptyView>.
CodePudding user response:
For generics the type should always be specified (explicitly or inferring) during specialisation, so the possible solution is to have helper init for that, like
init(text: LocalizedStringKey) where Header == EmptyView {
self.init(header: nil, text: text)
}
