SwiftUI 中的选择器选择和翻译冲突
Posted
技术标签:
【中文标题】SwiftUI 中的选择器选择和翻译冲突【英文标题】:Picker selection and translation conflict in SwiftUI 【发布时间】:2021-02-12 07:02:18 【问题描述】:我有一个带有 Picker 的可移动 VStack。当我想从 Picker 中选择不同的选项时,我不能,因为 SwiftUI 认为我想使用 DragGesture,因此我的 Picker 被锁定!我的 DragGesture 有 minimumDistance: 0 但是当我改变这个值时它也不能解决问题,另一方面我喜欢有 minimumDistance: 0 所以它甚至不是一个选项为我解决增加 minimumDistance 的问题,所以我需要帮助找到方法,谢谢。
struct ContentView: View
var body: some View
StyleView()
struct StyleView: View
@State private var location: CGSize = CGSize()
@GestureState private var translation: CGSize = CGSize()
@State private var styleIndex: Int = 0
let styles: [String] = ["a", "b", "c"]
var body: some View
VStack
Picker(selection: $styleIndex, label: Text("Style"))
ForEach(styles.indices, id:\.self) index in
Text(styles[index].description)
.pickerStyle(SegmentedPickerStyle())
.padding()
Text("selected style: " + styles[styleIndex])
.padding()
.background(Color.red)
.cornerRadius(10)
.padding()
.position(x: location.width + translation.width + 200, y: location.height + translation.height + 100)
.gesture(DragGesture(minimumDistance: 0)
.updating($translation) value, state, _ in
state = value.translation
.onEnded value in
location = CGSize(width: location.width + value.translation.width, height: location.height + value.translation.height)
)
【问题讨论】:
我知道你在你的问题中说你不想要任何最小距离,但是你确定它对你不起作用 - 将它设置为1
让选择器为我工作,似乎是一个非常小的副作用。我不确定它怎么会是 0,因为它永远无法区分拖动和点击。
我的意思是在 Picker 上拖动,通常我们可以用拖动来改变 Picker,如果我选择了 1 并且正如你所说的非常小,但是在选择器上拖动不起作用,你试过吗?
啊——我没明白那一点。好的,知道了。
例如如果使用minimumDistance=200就可以解决问题,但是在VStack上没有很好的拖动体验!拖动必须大于 200 才能开始拖动!
【参考方案1】:
DragGesture 在用户按下视图并至少移动一定距离时触发。因此,这会创建一个带有拖动手势的选取器,当用户将其移动至少 10 点时触发(它应该大于 0,否则它如何知道点击和拖动)
struct StyleView: View
@State private var location: CGSize = CGSize()
@GestureState private var translation: CGSize = CGSize()
@State private var styleIndex: Int = 0
let styles: [String] = ["a", "b", "c"]
var body: some View
VStack
Picker(selection: $styleIndex, label: Text("Style"))
ForEach(styles.indices, id:\.self) index in
Text(styles[index].description)
.gesture(DragAndTapGesture(count: styles.count, selected: $styleIndex).horizontal)
.pickerStyle(SegmentedPickerStyle())
.padding()
Text("selected style: " + styles[styleIndex])
.padding()
.background(Color.red)
.cornerRadius(10)
.padding()
.position(x: location.width + translation.width + 200, y: location.height + translation.height + 100)
.gesture(DragGesture(minimumDistance: 1)
.updating($translation) value, state, _ in
state = value.translation
.onEnded value in
location = CGSize(width: location.width + value.translation.width, height: location.height + value.translation.height)
)
struct DragAndTapGesture
var count: Int
@Binding var selected: Int
init(count: Int, selected: Binding<Int>)
self.count = count
self._selected = selected
var horizontal: some Gesture
DragGesture().onEnded value in
if -value.predictedEndTranslation.width > UIScreen.main.bounds.width / 2, self.selected < self.count - 1
self.selected += 1
if value.predictedEndTranslation.width > UIScreen.main.bounds.width / 2, self.selected > 0
self.selected -= 1
【讨论】:
我的意思是在 Picker 上拖拽,通常我们可以用拖拽来改变 Picker,如果我选择了 10 并且正如你所说的很小,但是在 Picker 上拖拽不起作用,你试过吗? 好的,我明白了,请参阅我编辑的答案。它可能会对你有所帮助。 我认为没有尊重,它不能解决问题 你现在检查了吗? 您是否也检查过设备,因为我可以轻松拖动以及点击选择器,并且拖动后值也会发生变化。增加 padding 区域,并更改选取器的背景颜色,使其易于区分。以上是关于SwiftUI 中的选择器选择和翻译冲突的主要内容,如果未能解决你的问题,请参考以下文章
选择器(SegmentedPickerStyle)中的选择效果不佳 - SwiftUI