如何使用 SwiftUI 拖动工作滑块
How to drag a working slider using SwiftUI
我想拖动一个滑块,当然也让它滑动。
我可以做其中之一,但我不能两者都做。
我怎样才能拖动并有一个工作滑块?
我也试图找到一种方法来删除手势,但我找不到这样做的方法。
还尝试了 Apple "Composing SwiftUI Gestures" 文档中的 "Sequenced Gesture States" 代码,
并引入一个标志来转动拖动 on/off 具有相同的结果,拖动或滑动不是两者。
我还尝试将滑块放入容器 (VStack) 并将拖动手势附加到其中,
但这也不起作用。
import SwiftUI
struct ContentView: View {
@State var pos = CGSize.zero
@State var acc = CGSize.zero
@State var value = 0.0
var body: some View {
let drag = DragGesture()
.onChanged { value in
self.pos = CGSize(width: value.translation.width + self.acc.width, height: value.translation.height + self.acc.height)
}
.onEnded { value in
self.pos = CGSize(width: value.translation.width + self.acc.width, height: value.translation.height + self.acc.height)
self.acc = self.pos
}
return Slider(value: $value, in: 0...100, step: 1)
.frame(width: 250, height: 40, alignment: .center)
.overlay(RoundedRectangle(cornerRadius: 25).stroke(lineWidth: 2).foregroundColor(Color.black))
.offset(x: self.pos.width, y: self.pos.height)
.simultaneousGesture(drag, including: .all) // tried .none .gesture, .subviews
// also tried .gesture(flag ? nil : drag)
}
}
对于 "simultaneousGesture",我希望同时操作两个手势。
这是有效的。基本上我需要在外部可观察对象中设置标志,以便它更新视图,以便它生效。当值更改时,标志设置为 false,但在十分之一秒后它变为可拖动。工作非常顺畅。
struct ContentView: View {
@State var pos = CGSize.zero
@State var acc = CGSize.zero
@State var value = 0.0
@ObservedObject var model = Model()
var body: some View {
let drag = DragGesture()
.onChanged { value in
self.pos = CGSize(width: value.translation.width + self.acc.width, height: value.translation.height + self.acc.height)
}
.onEnded { value in
self.pos = CGSize(width: value.translation.width + self.acc.width, height: value.translation.height + self.acc.height)
self.acc = self.pos
}
return VStack {
Slider(value: $value, in: 0...100, step: 1) { _ in
self.model.flag = false
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
self.model.flag = true
}
}
}
.frame(width: 250, height: 40, alignment: .center)
.overlay(RoundedRectangle(cornerRadius: 25).stroke(lineWidth: 2).foregroundColor(Color.black))
.offset(x: self.pos.width, y: self.pos.height)
.gesture(model.flag == true ? drag : nil)
}
}
class Model: ObservableObject {
@Published var flag = false
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
我想拖动一个滑块,当然也让它滑动。 我可以做其中之一,但我不能两者都做。 我怎样才能拖动并有一个工作滑块?
我也试图找到一种方法来删除手势,但我找不到这样做的方法。 还尝试了 Apple "Composing SwiftUI Gestures" 文档中的 "Sequenced Gesture States" 代码, 并引入一个标志来转动拖动 on/off 具有相同的结果,拖动或滑动不是两者。
我还尝试将滑块放入容器 (VStack) 并将拖动手势附加到其中, 但这也不起作用。
import SwiftUI
struct ContentView: View {
@State var pos = CGSize.zero
@State var acc = CGSize.zero
@State var value = 0.0
var body: some View {
let drag = DragGesture()
.onChanged { value in
self.pos = CGSize(width: value.translation.width + self.acc.width, height: value.translation.height + self.acc.height)
}
.onEnded { value in
self.pos = CGSize(width: value.translation.width + self.acc.width, height: value.translation.height + self.acc.height)
self.acc = self.pos
}
return Slider(value: $value, in: 0...100, step: 1)
.frame(width: 250, height: 40, alignment: .center)
.overlay(RoundedRectangle(cornerRadius: 25).stroke(lineWidth: 2).foregroundColor(Color.black))
.offset(x: self.pos.width, y: self.pos.height)
.simultaneousGesture(drag, including: .all) // tried .none .gesture, .subviews
// also tried .gesture(flag ? nil : drag)
}
}
对于 "simultaneousGesture",我希望同时操作两个手势。
这是有效的。基本上我需要在外部可观察对象中设置标志,以便它更新视图,以便它生效。当值更改时,标志设置为 false,但在十分之一秒后它变为可拖动。工作非常顺畅。
struct ContentView: View {
@State var pos = CGSize.zero
@State var acc = CGSize.zero
@State var value = 0.0
@ObservedObject var model = Model()
var body: some View {
let drag = DragGesture()
.onChanged { value in
self.pos = CGSize(width: value.translation.width + self.acc.width, height: value.translation.height + self.acc.height)
}
.onEnded { value in
self.pos = CGSize(width: value.translation.width + self.acc.width, height: value.translation.height + self.acc.height)
self.acc = self.pos
}
return VStack {
Slider(value: $value, in: 0...100, step: 1) { _ in
self.model.flag = false
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
self.model.flag = true
}
}
}
.frame(width: 250, height: 40, alignment: .center)
.overlay(RoundedRectangle(cornerRadius: 25).stroke(lineWidth: 2).foregroundColor(Color.black))
.offset(x: self.pos.width, y: self.pos.height)
.gesture(model.flag == true ? drag : nil)
}
}
class Model: ObservableObject {
@Published var flag = false
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}