Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot convert value of type [Type] to expected argument type 'some View'

Tags:

ios

swift

swiftui

I've got the following struct:

struct A : View {

    var backgroundView: some View = Color.white

    var body = some View {
        VStack {
            Text("abc")
        }
        .background(backgroundView)
    }

}

This works fine in preview, as long as I am not specifying my own backgroundView:

struct A_Previews: PreviewProvider {
    static var previews: some View {
        A()
    }
}

But when I specify the backgroundView to e.g. a LinearGradient:

struct A_Previews: PreviewProvider {
    static var previews: some View {
        A(backgroundView: LinearGradient(
             gradient: Gradient(colors: [.yellow, .white]),
             startPoint: .bottom,
             endPoint: .top))
    }
}

I get the following error:

Cannot convert value of type 'LinearGradient' to expected argument type 'some View'

Why does the default implementation work and why doesn't the custom declaration do? How can I set up a prameter that can accept both Color and LinearGradient types?

like image 903
iSpain17 Avatar asked Sep 06 '25 03:09

iSpain17


2 Answers

The best way to solve is using AnyView and wrapping the values inside it: based on this article: https://www.hackingwithswift.com/quick-start/swiftui/how-to-return-different-view-types

struct A : View {

    var backgroundView: AnyView = AnyView(Color.white)

    var body = some View {
        VStack {
            Text("abc")
        }
        .background(backgroundView)
    }

}

And then:

struct A_Previews: PreviewProvider {
    static var previews: some View {
        A(backgroundView: AnyView(LinearGradient(
             gradient: Gradient(colors: [.yellow, .white]),
             startPoint: .bottom,
             endPoint: .top)))
    }
}
like image 145
iSpain17 Avatar answered Sep 07 '25 19:09

iSpain17


You should use genericity. View contains reference to Self that's why you can't use it the way you wanted.

Try something like that :

struct A<BackgroundView : View> : View {

    var backgroundView: BackgroundView

    var body : some View {
        VStack {
            Text("abc")
        }
        .background(backgroundView)
    }

}

struct A_Previews: PreviewProvider {
    static var previews: some View {
        A(backgroundView: LinearGradient(
            gradient: Gradient(colors: [.yellow, .white]),
            startPoint: .bottom,
            endPoint: .top))
    }
}

And if you still need your default implementation, you can just add something like:

let defaultA = A(backgroundView: Color.white)

struct A_Previews: PreviewProvider {
    static var previews: some View {
        defaultA
    }
}
like image 39
Zaphod Avatar answered Sep 07 '25 19:09

Zaphod