I'm trying to build a view that is a rounded rectangle in a bar chart, with a gradient that gets progressively darker the higher value
is (value is on a 0-10.0 scale). But I can't seem to figure how how to use UnitPoint
here for endPoint to get the correct point where the gradient should end. In other words if value = 5.0, I want the gradient to show the top of the bar as half way to the gradient's darkest color, or said another way the gradient's darkest color is always at 10.0 and the bar's color will only show as high as the bar is.
var body: some View {
VStack {
RoundedRectangle(cornerRadius: 5.0)
.fill(LinearGradient(gradient: Gradient(colors: [ Color(UIColor(red: 0.98, green: 0.85, blue: 0.38, alpha: 1.00)) , Color(UIColor(red: 0.63, green: 0.02, blue: 0.11, alpha: 1.00))]), startPoint: .bottom, endPoint: UnitPoint(x: 0.5, y: CGFloat((value * 10 / 100)))))
.frame(width: 40, height: open ? CGFloat(value * 10) : 0)
}
}
I think your best bet is to "mask" the gradient, rather than trying to calculate the endPoint
.
Here's an example with 5 "bars" in an HStack
- the first bar has a max value of 10
, then the bars' values go 9, 7.5, 5, 2
:
Sample code:
import SwiftUI
struct GradBars: View {
var maxValue: CGFloat = 10
var val1: CGFloat = 10
var val2: CGFloat = 9
var val3: CGFloat = 7.5
var val4: CGFloat = 5
var val5: CGFloat = 2
@State var open: Bool = true
let gradient = LinearGradient(gradient: Gradient(colors: [ Color(UIColor(red: 0.98, green: 0.85, blue: 0.38, alpha: 1.00)) ,
Color(UIColor(red: 0.63, green: 0.02, blue: 0.11, alpha: 1.00))]),
startPoint: .bottom,
endPoint: .top)
var body: some View {
VStack {
HStack(alignment: .bottom, spacing: 8, content: {
Rectangle()
.fill(gradient)
.frame(width: 40, height: open ? maxValue * 10 : 0, alignment: .bottom)
.mask(
VStack {
RoundedRectangle(cornerRadius: 5.0).frame(height: val1 * 10)
}.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .bottom)
)
Rectangle()
.fill(gradient)
.frame(width: 40, height: open ? maxValue * 10 : 0, alignment: .bottom)
.mask(
VStack {
RoundedRectangle(cornerRadius: 5.0).frame(height: val2 * 10)
}.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .bottom)
)
Rectangle()
.fill(gradient)
.frame(width: 40, height: open ? maxValue * 10 : 0, alignment: .bottom)
.mask(
VStack {
RoundedRectangle(cornerRadius: 5.0).frame(height: val3 * 10)
}.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .bottom)
)
Rectangle()
.fill(gradient)
.frame(width: 40, height: open ? maxValue * 10 : 0, alignment: .bottom)
.mask(
VStack {
RoundedRectangle(cornerRadius: 5.0).frame(height: val4 * 10)
}.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .bottom)
)
Rectangle()
.fill(gradient)
.frame(width: 40, height: open ? maxValue * 10 : 0, alignment: .bottom)
.mask(
VStack {
RoundedRectangle(cornerRadius: 5.0).frame(height: val5 * 10)
}.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .bottom)
)
})
}
}
}
struct GradBars_Previews: PreviewProvider {
static var previews: some View {
GradBars()
}
}