如何使用 SwiftUI 拖动工作滑块 [英] How to drag a working slider using SwiftUI

查看:37
本文介绍了如何使用 SwiftUI 拖动工作滑块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I would like to drag a slider and of course have it slide as well. I can do one or the other, but I cannot do both. How can I drag and have a working slider?

我也试图找到一种删除手势的方法,但我找不到这样做的方法.还尝试了 AppleComposing SwiftUI Gestures"文档中的Sequenced Gesture States"代码,并引入一个标志来打开/关闭拖动,结果相同,拖动或滑动不要同时进行.

I also tried to find a way to remove a gesture, but I could not find a way to do that. Also tried the "Sequenced Gesture States" code from Apple "Composing SwiftUI Gestures" docs, and introduce a flag to turn the dragging on/off with same results, drag or slide not both.

我还尝试将滑块放在容器(VStack)中并将拖动手势附加到该容器中,但这也不起作用.

I also tried to put the slider in a Container (VStack) and attach the drag gesture to that, but that did not work either.

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",我期待同时操作两种手势.

With "simultaneousGesture" I was expecting to have both gestures operating at the same time.

推荐答案

这是有效的.基本上我需要在外部 observable 对象中设置标志以更新视图,以便它可以生效.当值改变时,标志被设置为 false,但在十分之一秒后它变成可拖动的.工作非常顺畅.

This is working. Basically I needed to set the flag in an outside observable object for it to update the view so that it could take effect. When the value changes the flag is set to false, but then after a tenth of a second it becomes draggable. Working pretty seamlessly.

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()
    }
}

这篇关于如何使用 SwiftUI 拖动工作滑块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆