无法将[Type]类型的值转换为预期的参数类型'some View'

时间:2019-12-18 13:14:16

标签: ios swift swiftui

我有以下结构:

tooltip

只要我未指定自己的struct A : View { var backgroundView: some View = Color.white var body = some View { VStack { Text("abc") } .background(backgroundView) } } ,这在预览中就可以正常工作:

backgroundView

但是当我将backgroundView指定为例如一个LinearGradient:

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

我收到以下错误:

  

无法将“ LinearGradient”类型的值转换为预期参数类型“ some View”

为什么默认实现起作用,为什么自定义声明不起作用?如何设置可以接受Color和LinearGradient类型的参数?

3 个答案:

答案 0 :(得分:1)

解决的最佳方法是使用AnyView并将其中的值包装起来:根据本文: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)
    }

}

然后:

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

答案 1 :(得分:0)

您应该使用通用性。 View包含对Self的引用,这就是为什么您无法按自己的方式使用它的原因。

尝试类似的事情:

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

如果仍然需要默认实现,则只需添加以下内容即可:

let defaultA = A(backgroundView: Color.white)

struct A_Previews: PreviewProvider {
    static var previews: some View {
        defaultA
    }
}

答案 2 :(得分:0)

我将以以下方式进行此操作(在Xcode 11.2上进行测试):

// Declarations >>>
struct A<Background> : View where Background : View {

    var backgroundView: Background

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

}

extension A where Background == Color {
    static var `default`: A<Color> {
        A<Color>(backgroundView: Color.white)
    }
}

// Testing >>>

struct TestSomeViewUsage: View {
    var body: some View {
        VStack {
            A.default
            Divider()
            A(backgroundView: LinearGradient(
                 gradient: Gradient(colors: [.yellow, .white]),
                 startPoint: .bottom,
                 endPoint: .top))
        }
    }
}

struct TestSomeViewUsage_Previews: PreviewProvider {
    static var previews: some View {
        TestSomeViewUsage()
    }
}