如何使用 SwiftUI 拖动工作滑块

Posted

技术标签:

【中文标题】如何使用 SwiftUI 拖动工作滑块【英文标题】:How to drag a working slider using SwiftUI 【发布时间】:2019-08-24 01:28:46 【问题描述】:

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

我也试图找到一种方法来移除手势,但我找不到这样做的方法。 还尝试了 Apple“撰写 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)


使用“simultaneousGesture”,我希望两个手势同时操作。

【问题讨论】:

很抱歉,我无法理解“拖动滑块”的工作原理。滑块的概念 - 无论是哪种语言 - 都意味着拖动正在工作滑块。你能举个例子吗?最好使用UIKit?自从您标记了这个 SwiftUI,我发现很多次要求使用 `UIKit1 的示例让我更清楚。 这里的想法是能够改变屏幕上的滑块位置(拖动它),就像你要在屏幕上拖动一个对象一样。这就是上面的代码所做的。但是,当屏幕上的这种拖动停止时,我希望能够使用滑块旋钮来更改滑块值,这就是我在问题中所说的幻灯片。 【参考方案1】:

这是有效的。基本上,我需要在外部可观察对象中设置标志,以更新视图,使其生效。当值更改时,标志设置为 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()
    

【讨论】:

太好了,谢谢它对我的目的来说足够好。我所做的唯一小改动是:@Published var flag = true 和 .gesture(model.flag ? drag : nil) 很高兴听到@workingdog。如果您想要回答,请不要忘记将答案标记为正确。最好的! 再次感谢。我试图标记你的答案,但我没有足够的声誉。对不起。也许其他人可以做到。 不行,只有提出问题的人才能将其标记为已回答。 请注意,使用“@State var flag = true”而不是“@ObservedObject var model = Model()”同样有效。

以上是关于如何使用 SwiftUI 拖动工作滑块的主要内容,如果未能解决你的问题,请参考以下文章

如何通过拖动滑块来控制我的 Kivy 滚动视图?

iPhone:如何检测滑块拖动的结束?

SwiftUI,如何在拖动后立即通过代码停止列表滚动?

您将如何在 swiftUI/Swift 的滑块轨道中绘制节点?

具有最大值的 SwiftUI 自定义滑块

可拖动 | jQuery 用户界面。如何在拖动事件上添加类