1

I'm trying to create a Set of cards. Each card has an object (shape) assigned, that is then shown with a different colour and appears in different numbers on each card. -> as a template I've created the struct SetCard

Already within the definition of the struct SetCard the var shape: Shape returns the error message:

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]

At a later step, the individual objects are shown and "stacked" on the same card:

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

What am I doing wrong here?

Definition of shapes:

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
    }
    
}
mundf
  • 23
  • 4

1 Answers1

0

You need to use one type for shape in your model, like

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

The AnyShape declaration and demo of usage can be observed in my different answer https://stackoverflow.com/a/62605936/12299030

And, of course, you have to update all other dependent parts to use it (I skipped that for simplicity).

Asperi
  • 228,894
  • 20
  • 464
  • 690