I'm pulling my hair out over here.
I'm just trying to produce a struct that has a member variable that can accept any shape, such as Circle(), Rectangle(), RoundedRectangle(), etc.
of course, the compiler is very mad about this, so I tried to write a function that takes an enum and returns 'some Shape' but that doesn't work because of opaque return types...
I'm thinking I need to build an 'AnyShape' using type erasure but it's super confusing to me. Does anyone know how to do this?
Looking for any helps / pointers you guys have. I've wasted hours on this.
public struct AnyShape: Shape {
private var base: (CGRect) -> Path
public init<S: Shape>(shape: S) {
base = shape.path(in:)
}
public func path(in rect: CGRect) -> Path {
base(rect)
}
}
Though I ask that you consider this carefully if you need type-erasure. In SwiftUI, chances are, you can do away with other mechanisms (like generic, if/else block).
Wow. Thank you so much for the help guys! I always feel weird stealing code but @mayoff your code really did work like a charm. Looks like it comes down to just passing along the path?
I’m struggling with something kind of similar. Anyone know how to let a ViewModifier know that it’s `contents is something that conforms to the Shape protocol ? I need a Shape stroked for a card game app ... and compiler complains that stroke() is not a member of Any view.
just as you noted to use it as a last resort only, is it possible to get rid of this type erasure in the following fragment without introducing code duplication?
One thing I would do, is to make Circle just a RoundedRectangle with infinite cornerRadius, or better yet, cornerRadius of width/2.
Swapping Shape like how you did it does lose the ability to animate shape transitions. It is probably fine otherwise to type-erase it since I just realise Shape does not participate in ViewBuilder, only View (which Shape conforms to).
Though I'd personally prefer to make it a proper shape
enum ImportantShape: Shape {
case square(Float), circle
func path(in rect: CGRect) -> Path { ... }
}
but that could just be me being paranoid about performance impact from type erasure, which used to be quite a problem in the past (not sure about now).