SwiftUI 中的自定义范围滑块
Custom range slider in SwiftUI
正在尝试使用 SwiftUI 中的值添加滑块最小和最大范围选择。
像上图一样添加最小值和最大值。
// define min & max value
@State var minValue: Float = 0.0
@State var maxValue: Float = Float(UIScreen.main.bounds.width - 50.0)
// setup slider view
ZStack (alignment: Alignment(horizontal: .leading, vertical: .center), content: {
Rectangle()
.fill(Color(UIColor.systemTeal).opacity(0.3))
.cornerRadius(30)
.frame(width: CGFloat(self.max), height: 30)
Rectangle()
.fill(Color.blue.opacity(25))
.cornerRadius(30)
.offset(x: CGFloat(self.min))
.frame(width: CGFloat((self.max + 20) - self.min), height: 30)
Circle()
.fill(Color.orange)
.frame(width: 30, height: 30)
.offset(x: CGFloat(self.min))
.gesture(DragGesture().onChanged({ (value) in
if value.location.x > 8 && value.location.x <= self.sliderWidth &&
value.location.x < CGFloat(self.max) {
self.min = Double(value.location.x)
}
}))
Circle()
.fill(Color.orange)
.frame(width: 30, height: 30)
.offset(x: CGFloat(self.max))
.gesture(DragGesture().onChanged({ (value) in
if value.location.x <= self.sliderWidth && value.location.x > CGFloat(self.min) {
self.max = Double(value.location.x)
}
}))
})
.padding()
在这段代码中,我遇到了最大值的问题,拖动最大值然后改变了滑块轨道的宽度,所以它没有完美移动。我尝试了不同的框架,但它不起作用。
终于找到答案了
// define min & max value
@State var minValue: Float = 0.0
@State var maxValue: Float = Float(UIScreen.main.bounds.width - 50.0)
// setup slider view
VStack {
HStack {
Text("0")
.offset(x: 28, y: 20)
.frame(width: 30, height: 30, alignment: .leading)
.foregroundColor(Color.black)
Spacer()
Text("100")
.offset(x: -18, y: 20)
.frame(width: 30, height: 30, alignment: .trailing)
.foregroundColor(Color.black)
}
ZStack(alignment: Alignment(horizontal: .leading, vertical: .center), content: {
Capsule()
.fill(Color.black.opacity(25))
.frame(width: CGFloat((UIScreen.main.bounds.width - 50) + 10), height: 30)
Capsule()
.fill(Color.black.opacity(25))
.offset(x: CGFloat(self.minValue))
.frame(width: CGFloat((self.maxValue) - self.minValue), height: 30)
Circle()
.fill(Color.orange)
.frame(width: 30, height: 30)
.background(Circle().stroke(Color.white, lineWidth: 5))
.offset(x: CGFloat(self.minValue))
.gesture(DragGesture().onChanged({ (value) in
if value.location.x > 8 && value.location.x <= (UIScreen.main.bounds.width - 50) &&
value.location.x < CGFloat(self.maxValue - 30) {
self.minValue = Float(value.location.x - 8)
}
}))
Text(String(format: "%.0f", (CGFloat(self.minValue) / (UIScreen.main.bounds.width - 50)) * 100))
.offset(x: CGFloat(self.minValue))
.frame(width: 30, height: 30, alignment: .center)
.foregroundColor(Color.black)
Circle()
.fill(Color.orange)
.frame(width: 30, height: 30)
.background(Circle().stroke(Color.white, lineWidth: 5))
.offset(x: CGFloat(self.maxValue - 18))
.gesture(DragGesture().onChanged({ (value) in
if value.location.x - 8 <= (UIScreen.main.bounds.width - 50) && value.location.x > CGFloat(self.minValue + 50) {
self.maxValue = Float(value.location.x - 8)
}
}))
Text(String(format: "%.0f", (CGFloat(self.maxValue) / (UIScreen.main.bounds.width - 50)) * 100))
.offset(x: CGFloat(self.maxValue - 18))
.frame(width: 30, height: 30, alignment: .center)
.foregroundColor(Color.black)
})
.padding()
}
正在尝试使用 SwiftUI 中的值添加滑块最小和最大范围选择。
像上图一样添加最小值和最大值。
// define min & max value
@State var minValue: Float = 0.0
@State var maxValue: Float = Float(UIScreen.main.bounds.width - 50.0)
// setup slider view
ZStack (alignment: Alignment(horizontal: .leading, vertical: .center), content: {
Rectangle()
.fill(Color(UIColor.systemTeal).opacity(0.3))
.cornerRadius(30)
.frame(width: CGFloat(self.max), height: 30)
Rectangle()
.fill(Color.blue.opacity(25))
.cornerRadius(30)
.offset(x: CGFloat(self.min))
.frame(width: CGFloat((self.max + 20) - self.min), height: 30)
Circle()
.fill(Color.orange)
.frame(width: 30, height: 30)
.offset(x: CGFloat(self.min))
.gesture(DragGesture().onChanged({ (value) in
if value.location.x > 8 && value.location.x <= self.sliderWidth &&
value.location.x < CGFloat(self.max) {
self.min = Double(value.location.x)
}
}))
Circle()
.fill(Color.orange)
.frame(width: 30, height: 30)
.offset(x: CGFloat(self.max))
.gesture(DragGesture().onChanged({ (value) in
if value.location.x <= self.sliderWidth && value.location.x > CGFloat(self.min) {
self.max = Double(value.location.x)
}
}))
})
.padding()
在这段代码中,我遇到了最大值的问题,拖动最大值然后改变了滑块轨道的宽度,所以它没有完美移动。我尝试了不同的框架,但它不起作用。
终于找到答案了
// define min & max value
@State var minValue: Float = 0.0
@State var maxValue: Float = Float(UIScreen.main.bounds.width - 50.0)
// setup slider view
VStack {
HStack {
Text("0")
.offset(x: 28, y: 20)
.frame(width: 30, height: 30, alignment: .leading)
.foregroundColor(Color.black)
Spacer()
Text("100")
.offset(x: -18, y: 20)
.frame(width: 30, height: 30, alignment: .trailing)
.foregroundColor(Color.black)
}
ZStack(alignment: Alignment(horizontal: .leading, vertical: .center), content: {
Capsule()
.fill(Color.black.opacity(25))
.frame(width: CGFloat((UIScreen.main.bounds.width - 50) + 10), height: 30)
Capsule()
.fill(Color.black.opacity(25))
.offset(x: CGFloat(self.minValue))
.frame(width: CGFloat((self.maxValue) - self.minValue), height: 30)
Circle()
.fill(Color.orange)
.frame(width: 30, height: 30)
.background(Circle().stroke(Color.white, lineWidth: 5))
.offset(x: CGFloat(self.minValue))
.gesture(DragGesture().onChanged({ (value) in
if value.location.x > 8 && value.location.x <= (UIScreen.main.bounds.width - 50) &&
value.location.x < CGFloat(self.maxValue - 30) {
self.minValue = Float(value.location.x - 8)
}
}))
Text(String(format: "%.0f", (CGFloat(self.minValue) / (UIScreen.main.bounds.width - 50)) * 100))
.offset(x: CGFloat(self.minValue))
.frame(width: 30, height: 30, alignment: .center)
.foregroundColor(Color.black)
Circle()
.fill(Color.orange)
.frame(width: 30, height: 30)
.background(Circle().stroke(Color.white, lineWidth: 5))
.offset(x: CGFloat(self.maxValue - 18))
.gesture(DragGesture().onChanged({ (value) in
if value.location.x - 8 <= (UIScreen.main.bounds.width - 50) && value.location.x > CGFloat(self.minValue + 50) {
self.maxValue = Float(value.location.x - 8)
}
}))
Text(String(format: "%.0f", (CGFloat(self.maxValue) / (UIScreen.main.bounds.width - 50)) * 100))
.offset(x: CGFloat(self.maxValue - 18))
.frame(width: 30, height: 30, alignment: .center)
.foregroundColor(Color.black)
})
.padding()
}