I have the following code:
struct TestContainer: View {
@State var useGradient = false
var body: some View {
ZStack {
Color.black
Button {
} label: {
RoundedRectangle(cornerRadius: .infinity)
.fill(useGradient ? buttonGradient() as! Color : Color.green)
.overlay {
Text("Done")
.font(.system(size: 17, weight: .semibold))
.foregroundStyle(.white)
}
.cornerRadius(.infinity)
}
.frame(height: 44)
.padding(.horizontal, 40)
}
}
private func buttonGradient() -> some View {
return LinearGradient(
stops: [
Gradient.Stop(color: Color(red: 0.1, green: 0.2, blue: 0.2), location: 0.00),
Gradient.Stop(color: Color(red: 0.1, green: 0.3, blue: 0), location: 1.00),
],
startPoint: UnitPoint(x: 0, y: 1),
endPoint: UnitPoint(x: 1, y: 0)
)
}
}
At times I get:
Could not cast value of type 'SwiftUI.LinearGradient' (0x1f2bf7980) to 'SwiftUI.Color' (0x1f2c1b688).
How can I make this work where depending on the useGradient
state the fill changes?
The suggestions in the comments provide a couple of ways of doing this.
Another way would be to use a generic function that receives a ShapeStyle
as parameter. This requires that the gradient is delivered as some ShapeStyle
instead of as some View
:
struct TestContainer: View {
@State var useGradient = false
private func buttonLabel<F: ShapeStyle>(fillStyle: F) -> some View {
RoundedRectangle(cornerRadius: .infinity)
.fill(fillStyle)
.overlay {
Text("Done")
.font(.system(size: 17, weight: .semibold))
.foregroundStyle(.white)
}
.cornerRadius(.infinity)
}
private var buttonGradient: some ShapeStyle {
LinearGradient(
stops: [
Gradient.Stop(color: Color(red: 0.1, green: 0.2, blue: 0.2), location: 0.00),
Gradient.Stop(color: Color(red: 0.1, green: 0.3, blue: 0), location: 1.00),
],
startPoint: UnitPoint(x: 0, y: 1),
endPoint: UnitPoint(x: 1, y: 0)
)
}
var body: some View {
ZStack {
Color.black
Button {
useGradient.toggle()
} label: {
if useGradient {
buttonLabel(fillStyle: buttonGradient)
} else {
buttonLabel(fillStyle: .green)
}
}
.frame(height: 44)
.padding(.horizontal, 40)
}
}
}