1

I'm trying to create a custom linear gauge style, but I'm wondering on how is the best way to make the circle move following the value. As you can notice I have tried with offset but it stay in place.

struct LightBarGaugeStyle: GaugeStyle {
    
    private var gradient = LinearGradient(colors: [.blue, .yellow, .orange, .red], startPoint: .leading, endPoint: .trailing)
    
    func makeBody(configuration: Configuration) -> some View {
        VStack(alignment: .leading, spacing: 0) {
            Circle()
                .frame(width: 20)
                .foregroundColor(.blue)
                .offset(x: configuration.value)
            Capsule()
                .fill(gradient)
                .frame(width: 1000, height: 30)
                .overlay {
                    Capsule()
                        .stroke(lineWidth: 2)
                        .frame(width: 1000, height: 30)
                        .foregroundColor(.black)
                }
            
           
        }
    }
}

2 Answers2

0

You can add GeometryReader to make the circle move following the value of the gauge, you can modify the code as follows:

struct LightBarGaugeStyle: GaugeStyle {
    private var gradient = LinearGradient(colors: [.blue, .yellow, .orange, .red], startPoint: .leading, endPoint: .trailing)

    func makeBody(configuration: Configuration) -> some View {
        VStack(alignment: .leading, spacing: 0) {
            GeometryReader { geometry in
                ZStack(alignment: .leading) {
                    Capsule()
                        .fill(gradient)
                        //.frame(width: 1000, height: 30)
                        .frame(width: geometry.size.width, height: 30)
                        .overlay {
                            Capsule()
                                .stroke(lineWidth: 2)
                                //.frame(width: 1000, height: 30)
                                .frame(width: geometry.size.width, height: 30)
                                .foregroundColor(.black)
                        }
                    Circle()
                        .frame(width: 20)
                        .foregroundColor(.blue)
                        //.offset(x: configuration.value)
                        .offset(x: geometry.size.width * CGFloat(configuration.value))
                }
            }
        }
    }
}
baohoang
  • 616
  • 1
  • 5
  • 13
0

I have tried with offset but it stay in place.

Actually it's not staying in place, it's just the offset is too small to be noticed. If you tried to print out the actual value of configuration.value, you will notice the value is between 0 and 1.

Instead, you would want to have the value multiply by the width, and then you will see the circle move along the line as wanted:

Circle()
    .offset(x: configuration.value * 1000)
Ranoiaetep
  • 5,872
  • 1
  • 14
  • 39