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)
}