SwiftUI 4 新特性 Gauge 版本要求: iOS 16.0+
iPadOS 16.0+
macOS 13.0+
Mac Catalyst 16.0+
watchOS 7.0+
Gauge
是一个新的仪表盘进度条控件,跟 ProgressView
不一样,它可以展示不同形状样式的进度条,它可以配置成像汽车的时速燃油表,显示当前值,起止范围值,不同区域颜色样式等。
主要API
func gaugeStyle<S>(S) -> some View
自带的样式:
.automatic
自动
.accessoryCircular
圆环 (底部有缺口) 的仪表样式
.accessoryCircularCapacity
圆环 (完整圆圈) 的仪表样式
.linearCapacity
基础条形样式
.accessoryCircularCapacity
带有简要信息标记的条形样式 (最小值, 最大值)
.accessoryCircularCapacity
带有更多信息的条形样式 (视图文本, 最小值, 最大值, 当前值)
需要更多样式可以实现 GaugeStyle
末尾附自定义样式示例代码
示例代码
struct GaugeView: View {
@State var loading = 85.0
@State var speed = 86.0
@State var val = 32.0
var body: some View {
VStack {
HStack(spacing: 64) {
VStack {
Text("温度计")
Gauge(value: val, in: 0...45) {
} currentValueLabel: {
Text("\(String(format: "%.f", val))°")
.font(.caption)
} minimumValueLabel: {
Text("0°")
.font(.caption2)
} maximumValueLabel: {
Text("40°")
.font(.caption2)
}
.gaugeStyle(.accessoryCircular)
.tint(Gradient(colors: [.green, .yellow, .orange, .red]))
}
VStack {
Text("温度计")
Gauge(value: val, in: 0...45) {
Text("\(String(format: "%.f", val))°")
.font(.caption)
}
.gaugeStyle(.accessoryCircularCapacity)
.progressViewStyle(.linear)
.tint(.orange)
}
}
.padding()
Gauge(value: speed, in: 0...120) {
Text("时速")
} currentValueLabel: {
Text("\(String(format: "%.f", speed)) km/h")
} minimumValueLabel: {
Text("0 km/h")
.font(.system(size: 10))
} maximumValueLabel: {
Text("120 km/h")
.font(.system(size: 10))
}
.gaugeStyle(.linearCapacity)
.tint(Gradient(colors: [.blue, .green, .yellow, .red]))
.padding()
}
}
}
自定义时速仪表盘样式
import SwiftUI
struct GaugeSpeedStyle: GaugeStyle {
private var purpleGradient = LinearGradient(gradient: Gradient(colors: [ .gray, .blue ]), startPoint: .trailing, endPoint: .leading)
func makeBody(configuration: Configuration) -> some View {
ZStack {
Circle()
.foregroundColor(.gray.opacity(0.15))
Circle()
.trim(from: 0, to: 0.75 * configuration.value)
.stroke(purpleGradient, lineWidth: 20)
.rotationEffect(.degrees(135))
Circle()
.trim(from: 0, to: 0.75)
.stroke(Color.red, style: StrokeStyle(lineWidth: 5, lineCap: .butt, lineJoin: .round, dash: [1, 8], dashPhase: 0.0))
.rotationEffect(.degrees(135))
Circle()
.trim(from: 0, to: 0.75)
.stroke(Color.black, style: StrokeStyle(lineWidth: 10, lineCap: .butt, lineJoin: .round, dash: [1, 35], dashPhase: 0.0))
.rotationEffect(.degrees(135))
VStack {
configuration.currentValueLabel
.font(.system(size: 80))
Text("km/h")
.font(.body)
.bold()
}
.fontWeight(.semibold)
.fontDesign(.rounded)
.foregroundColor(.black.opacity(0.8))
}
.frame(width: 240, height: 240)
}
}