无法将 [Type] 类型的值转换为预期的参数类型"某些视图"



我有以下结构:

struct A : View {
var backgroundView: some View = Color.white
var body = some View {
VStack {
Text("abc")
}
.background(backgroundView)
}
}

这在预览中工作正常,只要我不指定自己的backgroundView

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

但是当我指定背景视图时,例如线性渐变:

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

我收到以下错误:

无法将类型"线性梯度"的值转换为预期的参数类型"某些视图">

为什么默认实现有效,为什么自定义声明不起作用?如何设置可以同时接受颜色和线性渐变类型的温度计?

最好的解决方法是使用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)))
}
}

你应该使用通用性。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
}
}

我会通过以下方式执行此操作(在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()
}
}

最新更新