I need to make something that can be used anywhere LinearGradient, AngularGradient and RadialGradient can be used. Since these are ShapeStyle, View, so I think what I need is to implement something like this:
struct MySomeGradient: ShapeStyle, View {
let gradient: (What' type here?)
// I know all the key values, in fact, its an enum
init(key: String) {
// will create any of LinearGradient, AngularGradient or RadialGradiant base on value of key
if key == "AAAA" {
self.gradient = LinearGradient(...)
} else if key == "BBBB" {
self.gradient = AngularGradient(...)
} else if key == "CCCC" {
self.gradient = RadialGradient(....)
} else if etc ete {
self.gradient = some gradient ...
}
}
// so how to implement this?
}
struct MySomeGradient<Content: ShapeStyle & View>: ShapeStyle, View {
static func _makeView<S>(view: _GraphValue<_ShapeView<S, ThemeColor<Content>>>, inputs: _ViewInputs) -> _ViewOutputs where S : Shape {
<#code#> // 😳
}
let gradient: Content
enum Key: String, CaseIterable {
case grain = "稻谷"
case rainbow = "rainbow"
case daynight = "daynight"
}
// I know all the key values, in fact, its an enum
init(key: String) {
// will create any of LinearGradient, AngularGradient or RadialGradiant base on value of key
if key == "AAAA" {
self.gradient = LinearGradient(...)
} else if key == "BBBB" {
self.gradient = AngularGradient(...)
} else if key == "CCCC" {
self.gradient = RadialGradient(....)
} else if etc ete {
self.gradient = some gradient ...
}
}
var body: some View {
gradient
}
}
So I let Xcode fill in the protocol stub and got this _makeView<S>(....). Do all these _ means this is not for public use?
Newly introduced in Xcode Version 13.0 beta 3 (13A5192i) (SwiftUI 3 beta 3?): AnyShapeStyle makes this possible:
struct GradientView: View {
let gradient: AnyShapeStyle
enum Key: String, CaseIterable {
case grain = "稻谷"
case rainbow = "rainbow"
case daynight = "daynight"
}
// I know all the key values, in fact, its an enum
init(_ key: Key) {
// will create any of LinearGradient, AngularGradient or RadialGradiant base on value of key
switch key {
case .grain:
gradient = AnyShapeStyle( // can now type erase!!!
.linearGradient(colors: [.red, .blue, .teal], startPoint: .topLeading, endPoint: .bottomTrailing)
)
case .rainbow:
gradient = AnyShapeStyle(
Color.yellow
)
case .daynight:
gradient = AnyShapeStyle(
.conicGradient(Gradient(colors: [.yellow, .cyan, .purple]), center: .center)
)
}
}
var body: some View {
Rectangle()
// can be filled with whatever
.fill(gradient)
}
}