我是 SwiftUI 的新手,我正在尝试使用 SwiftUI 设计车辆的速度计,为此我检查了各种解决方案,但所有解决方案都是圆形或线性水平的,但我需要它完全定制。
内容视图
import SwiftUI
struct SpeedometerGaugeStyle: GaugeStyle {
private var numberOfIterations = 40
private var purpleGradient = LinearGradient(gradient: Gradient(colors:
[ Color.red,
Color.green,
Color.blue
]),
startPoint: .topLeading, endPoint: .bottomTrailing)
func makeBody(configuration: Configuration) -> some View {
VStack {
ForEach((1...20), id: \.self) { index in
RoundedRectangle(cornerSize: CGSize(width: 100, height: 10))
.frame(width: (Double(100 - ( index * 2 )) ), height: 10)
.foregroundStyle(ColorGradient.putIndex(index: index))
}
}
}
struct ColorGradient {
static func putIndex(index : Int) -> LinearGradient {
switch index {
case 0...4:
return LinearGradient(colors: [
Color.red,
Color.red.opacity(0.7),
Color.red.opacity(0.6),
Color.red.opacity(0.5)
],
startPoint: .bottom, endPoint: .top)
case 4...8:
return LinearGradient(colors: [
Color.orange,
Color.orange.opacity(0.7),
Color.orange.opacity(0.6),
Color.orange.opacity(0.5)
],
startPoint: .bottom, endPoint: .top)
case 8...16:
return LinearGradient(colors: [
Color.cyan,
Color.cyan.opacity(0.7),
Color.cyan.opacity(0.6),
Color.cyan.opacity(0.5)
],
startPoint: .bottom, endPoint: .top)
default:
return LinearGradient(colors: [
Color.green,
Color.green.opacity(0.8),
Color.green.opacity(0.9),
Color.green.opacity(1.0)
],
startPoint: .bottom, endPoint: .top)
}
}
}
}
struct CustomGaugeView: View {
@State private var currentSpeed = 45.0
@State private var animateGradient = false
var body: some View {
VStack {
Gauge(value: currentSpeed, in: 0...160) {
Text(currentSpeed.debugDescription)
} currentValueLabel: {
Text("\(currentSpeed.formatted(.number))")
.foregroundColor(Color.white)
}
.gaugeStyle(SpeedometerGaugeStyle())
.frame(width: 200, height: 300)
Spacer()
Slider(value: $currentSpeed, in: 0...160) {
EmptyView()
}
Spacer()
}
}
}
主要
@main
struct Speedometer_DemoApp: App {
var body: some Scene {
WindowGroup {
CustomGaugeView()
.previewDisplayName("CustomGaugeView")
}
}
}
任何人都可以帮助我使用 SwiftUI 获取这种类型的仪表吗? 预先感谢
您需要配置值才能使其工作。
struct SpeedometerGaugeStyle: GaugeStyle {
private var numberOfIterations = 20
private var purpleGradient = LinearGradient(gradient: Gradient(colors:
[ Color.red,
Color.green,
Color.blue
]),
startPoint: .topLeading, endPoint: .bottomTrailing)
func makeBody(configuration: Configuration) -> some View {
GeometryReader { geometry in
VStack(alignment: .leading) {
ForEach((0... numberOfIterations).reversed(), id: \.self) { index in
RoundedRectangle(cornerSize: CGSize(width: 100, height: 10))
.frame(width: (Double(100 + ( index * 2 )) ), height: 5)
.foregroundStyle(ColorGradient.putIndex(index: index))
.opacity((configuration.value * numberOfIterations) > Double(index) ? 1 : 0.3)
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
}
对齐方式:vstack 中的 .leading 将其推到一侧 .trailing 将其切换到另一侧。
我还切换了颜色渐变,从绿色变为红色
struct ColorGradient {
static func putIndex(index : Int) -> LinearGradient {
switch index {
case 0...4:
return LinearGradient(colors: [
Color.green,
Color.green.opacity(0.8),
Color.green.opacity(0.9),
Color.green.opacity(1.0)
],
startPoint: .bottom, endPoint: .top)
case 4...8:
return LinearGradient(colors: [
Color.cyan,
Color.cyan.opacity(0.7),
Color.cyan.opacity(0.6),
Color.cyan.opacity(0.5)
],
startPoint: .bottom, endPoint: .top)
case 8...15:
return LinearGradient(colors: [
Color.orange,
Color.orange.opacity(0.7),
Color.orange.opacity(0.6),
Color.orange.opacity(0.5)
],
startPoint: .bottom, endPoint: .top)
default:
return LinearGradient(colors: [
Color.red,
Color.red.opacity(0.7),
Color.red.opacity(0.6),
Color.red.opacity(0.5)
],
startPoint: .bottom, endPoint: .top)
}
}
}