skip to Main Content

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 ?

2

Answers


  1. 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>.

    Login or Signup to reply.
  2. 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)
     }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search