不能在 SwiftUI 中使用 'shape' 作为类型

Can't use 'shape' as Type in SwiftUI

我正在尝试创建一套卡片。每张卡片都分配了一个对象(形状),然后以不同的颜色显示并在每张卡片上以不同的数字显示。 -> 作为模板,我创建了 struct SetCard

内部已经定义了struct SetCard var shape: Shape returns 错误信息:

Value of protocol type 'Shape' cannot conform to 'View'; only struct/enum/class types can conform to protocols"

import Foundation
import SwiftUI

var setCardSet: Array<SetCard> = []
var counter: Int = 0

func createSet() -> Array<SetCard> {
    for object in 0..<3 {
        var chosenShape = objectLibrary[object]
        for color in 0..<3 {
            var chosenColor = colors[color]
            for numberOfShapes in 0..<3 {
                counter += 1
                setCardSet.append(SetCard(id: counter, shape: chosenShape, numberOfShapes: numberOfShapes, colorOfShapes: chosenColor))
            }
        }
    }
    return setCardSet
}


struct SetCard: Identifiable {
    var id: Int
    var shape: Shape
    var numberOfShapes: Int
    var colorOfShapes: Color
//        var shadingOfShapes: Double
}

struct GameObject {
    var name: String
    var object: Shape
}

let objectLibrary: [Shape] = [Diamond(), Oval()]
let colors: [Color] = [Color.green, Color.red, Color.purple]

在稍后的步骤中,各个对象将显示并“堆叠”在同一张卡片上:

import SwiftUI

struct ContentView: View {
    let observed: Array<SetCard> = createSet()
    
    var body: some View {
        VStack (observed) { card in
            CardView(card: card).onTapGesture {
                withAnimation(.linear(duration: 0.75)) {
                    print(card.id)
                }
            }
            .padding(2)
        }
    }
}

struct CardView: View {
    var card: SetCard
    
    var body: some View {
        ZStack {
            VStack{
                ForEach(0 ..< card.numberOfShapes+1) {_ in
                    card.shape
                }
            }
        }
    }
}

let gradientStart = Color(red: 239.0 / 255, green: 120.0 / 255, blue: 221.0 / 255)
let gradientEnd = Color(red: 239.0 / 255, green: 172.0 / 255, blue: 120.0 / 255)


struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

我做错了什么?

形状定义:

import SwiftUI

struct Diamond: Shape  {
    
    func path(in rect: CGRect) -> Path {
        
        let height = min(rect.width, rect.height)/4
        let length = min(rect.width, rect.height)/3
        
        let center = CGPoint(x: rect.midX, y: rect.midY)
        let top: CGPoint = CGPoint(x: center.x + length, y: center.y)
        let left: CGPoint = CGPoint(x: center.x, y: center.y - height)
        let bottom: CGPoint = CGPoint(x: center.x - length, y: center.y)
        let right: CGPoint = CGPoint(x: center.x, y: center.y + height)

        var p = Path()
        p.move(to: top)
        p.addLine(to: left)
        p.addLine(to: bottom)
        p.addLine(to: right)
        p.addLine(to: top)
        
        return p
    }
}

struct Oval: Shape {
    func path(in rect: CGRect) -> Path {

        let height = min(rect.width, rect.height)/4
        let length = min(rect.width, rect.height)/3
        
        let center = CGPoint(x: rect.midX, y: rect.midY)
        let centerLeft = CGPoint(x: center.x - length + (height/2), y: center.y)
        let centerRight = CGPoint(x: center.x + length - (height/2), y: center.y)
        let bottomRight = CGPoint(x: centerRight.x, y: center.y - height)
        let topLeft = CGPoint(x: centerLeft.x, y: center.y + height)
        
        var p = Path()
        p.move(to: topLeft)
        p.addArc(center: centerLeft, radius: height, startAngle: Angle(degrees: 90), endAngle: Angle(degrees: 270), clockwise: false)
        p.addLine(to: bottomRight)
        p.addArc(center: centerRight, radius: height, startAngle: Angle(degrees: 270), endAngle: Angle(degrees: 90), clockwise: false)
        p.addLine(to: topLeft)

        return p
    }
    
}

您需要在模型中使用一种类型的形状,例如

struct SetCard: Identifiable {
    var id: Int
    var shape: AnyShape          // << here !!
    var numberOfShapes: Int
    var colorOfShapes: Color
//        var shadingOfShapes: Double
}

AnyShape声明和用法演示可以在我的不同答案中观察

当然,您必须更新所有其他依赖部分才能使用它(为简单起见,我跳过了它)。