Goal:
To have a single struct to manage the appearance and behavior of a custom View
.
Status: I have a simple view model which maintains an array of data representing the view. At run time, I draw these views as follows:
struct MyView: View {
@ObservedObject var viewModel = MyViewModel()
var body: some View {
Vstack() {
ForEach(viewModel.data, id: \.id) { data in
switch data.shape {
case .circle:
MyViewCircle(isHighlighted: data.willHighlight)
case .ellipses:
MyViewEllipses(isHighlighted: data.willHighlight)
}
}
}
}
}
struct MyViewCircle: View {
var isHighlighted: Bool
var body: some View {
Circle()
/// a bunch of modifiers
}
}
struct MyViewEllipses: View {
var isHighlighted: Bool
var body: some View {
Ellipses()
///A bunch of modifiers that mirror exactly MyViewCircle
}
}
This works fine and I am able to update my viewModel which will update my views accordingly.
However, in my case, MyViewCircle
or MyViewEllipses
will have the exact same appearance and behavior, and the only thing different is it's Shape, also I plan on adding a number of other shapes and even custom drawn shapes.
What I'd like to do
I'd like to be able to pass an enum
or protocol
or something in my ForEach loop that would draw the shape I want and simplify without the need for a long switch statement. Something like this:
struct MyView: View {
@ObservedObject var viewModel = MyViewModel()
var body: some View {
VStack() {
ForEach(viewModel.data, id: \.id) { data in
MyViewProtocol(shape: data.shape, isHighlighted: data.IsHighlighted)
}
}
}
}
And the Parent, Super class, protocol, whatever the proper name for MyViewProtocol
would look something like:
struct MyViewProtocol: View {
var shape: ShapeEnum
var isHighlighted: Bool
var body: some View {
switch shape:
case .circle:
Circle()
case .ellipses:
Ellipses()
case .triangle:
MyTrinagle()
// etc.....
}
}
I have been scouring any/all WWDC talks, YouTube tutorials, medium articles, and the closest thing I could find was on SO here: Creating BaseView class in SwiftUI which is useful for creating a set of modifiers of views, however I'm still in a lurch if I want to be able to use a plethora of shapes managed by one parent struct view.
I may also be having problems because perhaps this is a red flag bad design pattern for a declarative language like SwiftUI!
I would be so grateful for any tips or ideas!