iosswiftswiftuigauge

Changing size of Gauge element


I created a circular gauge for progressive view with stop button in middle of it, but the circle looks quite big. I am unable to reduce it's size. How do I change the size of circle?

Code:

import SwiftUI

struct DownloadProgressGauge: View {
    var body: some View {
        Gauge(value: 100, in: 0...200) {
            Image(systemName: "gauge.medium").resizable().frame(width: 30, height: 30.0)
        } currentValueLabel: {
            Image(systemName: "stop.fill").font(.caption).bold()
                .foregroundStyle(Color.systemBlue)
                .minimumScaleFactor(0.33)
        }
        .gaugeStyle(.accessoryCircularCapacity)
        .tint(Color.systemBlue)
        .frame(width: 30, height: 30)
    }
} 

This is how big circle looks after running the code:

enter image description here

I am looking for something like this i.e. gauge in smaller size:

enter image description here


Solution

  • You can make almost anything smaller with scaleEffect. Combine that with a larger image for the stop button, and you get something similar to the proportions you want:

    Gauge(value: 100, in: 0...200) {
        
    } currentValueLabel: {
        Image(systemName: "stop.fill").resizable().bold().frame(width: 18, height: 18)
            .foregroundStyle(Color.blue)
    }
    .gaugeStyle(.accessoryCircularCapacity)
    .tint(Color.blue)
    .scaleEffect(0.5)
    

    enter image description here


    That said, I don't recommend using a built-in GaugeStyle if you have a very specific design in mind. You can create your own GaugeStyle.

    struct VariableSizeCircularStyle: GaugeStyle {
        func makeBody(configuration: Configuration) -> some View {
            ZStack {
                Circle()
                    .stroke(.primary.opacity(0.5), lineWidth: 4)
                Circle()
                    .trim(to: configuration.value)
                    .stroke(.primary, style: .init(lineWidth: 4, lineCap: .round))
                    .rotationEffect(.degrees(-90))
                configuration.currentValueLabel
            }
        }
    }
    
    extension GaugeStyle where Self == VariableSizeCircularStyle {
        static var variableSizeCircular: VariableSizeCircularStyle { .init() }
    }
    
    // Usage:
    
    struct ContentView: View {
        
        var body: some View {
            Gauge(value: 100, in: 0...200) {
                
            } currentValueLabel: {
                Image(systemName: "stop.fill").resizable().bold().frame(width: 12, height: 12)
            }
            .gaugeStyle(.variableSizeCircular)
            .foregroundStyle(Color.blue)
            .frame(width: 30, height: 30)
        }
    }