I'm rendering some views that have a dynamic list of modifiers:
public enum Colors:String, CaseIterable {
public func to_color() -> Color {
color_hex(self.rawValue)
}
case black = "#000000"
case white = "#FFFFFF"
case gray_500 = "#F9FAFB"
case blue_200 = "#BFDBFE"
case blue_500 = "#3B82F6"
}
public enum Style {
case bg(Colors)
case text(Colors)
}
struct StyleModifier: ViewModifier {
fileprivate let properties: [Style]
func body(content: _ViewModifier_Content<StyleModifier>) -> some View {
return apply(content: content.toAnyView(), properties)
}
}
public extension View {
func toAnyView() -> AnyView {
return AnyView(self)
}
func style(_ clsName: [Style]) -> some View {
ModifiedContent(content: self, modifier: StyleModifier(properties: clsName))
}
func style2(_ clsName: [Style]) -> some View {
ModifiedContent(content: self, modifier: StyleModifier2(properties: clsName))
}
}
... and try to make this without resorting to AnyView
but nothings get applied.
My working code with AnyView
:
func apply(content: AnyView, _ properties: [Style]) -> AnyView {
return properties.reduce(content) { (v: AnyView, style: Style) -> AnyView in
switch style {
case .bg(let color):
return v.background(color.to_color()).toAnyView()
case .text(let color):
return v.foregroundColor(color.to_color()).toAnyView()
}
}
I try to translate this with generics:
func apply2<V: View>(of: V, _ properties: [Style]) -> V {
return properties.reduce(of) { (v: V, style: Style) -> V in
switch style {
case .bg(let color):
return v.background(color.to_color()) as! V
case .text(let color):
return v.foregroundColor(color.to_color()) as! V
}
}
But then this not work. Why?