如何使用 SwiftUI 拖动工作滑块

wor*_*dog 2 swift swiftui

我想拖动一个滑块,当然也让它滑动。我可以做一个或另一个,但我不能两者都做。我怎样才能拖动并有一个工作滑块?

我也试图找到一种方法来删除一个手势,但我找不到一种方法来做到这一点。还尝试了 Apple“Composing SwiftUI Gestures”文档中的“Sequenced Gesture States”代码,并引入了一个标志来打开/关闭拖动,结果相同,拖动或滑动不是两者。

我还尝试将滑块放在容器(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)
}
}
Run Code Online (Sandbox Code Playgroud)

使用“simultaneousGesture”,我期待同时操作两种手势。

MSc*_*ler 5

这是有效的。基本上我需要在外部 observable 对象中设置标志以更新视图,以便它可以生效。当值改变时,标志被设置为 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()
    }
}
Run Code Online (Sandbox Code Playgroud)