让我们看看这段代码:
@State private var progress: TimeInterval = 0
@State private var sliderMoving: Bool = false
Slider(value: $progress, in: 0 ... Double(100), onEditingChanged: { didChange in
seekToProgress(p: progress)
}).simultaneousGesture(
DragGesture(minimumDistance: 0)
.onChanged { gesture in
print("gesture onChanged")
sliderMoving = true
}
.onEnded { gesture in
print("gesture onEnded")
sliderMoving = false
}
)
我想跟踪滑块上的触摸和结束事件,但这会阻止实际的滑块被触摸。换句话说,DragGesture似乎消耗触摸,尽管使用了simultaneousGesture。我也试过添加GestureMask.all,但也不起作用。我该怎么解决这个问题?我需要跟踪触摸下/上,因为这个滑块是用来寻求一个音频轨道,但也音频轨道更新滑块。但是,当用户触摸滑块时,它不应该这样做(sliderMoving标志应该处理这个问题)。
类似的方法适用于按钮敲击,但不适用于滑块移动。
编辑:
我发布了最终答案,感谢@Marco Boerner的大力帮助:
GeometryReader { geometry in
Slider(value: $progress, in: 0 ... Double(100), onEditingChanged: { didChange in
print("onEditingChanged") //not used
})
.simultaneousGesture(
DragGesture(minimumDistance: 0)
.onChanged { gesture in
sliderMoving = true
updateProgress(x: gesture.location.x, width: geometry.size.width)
}
.onEnded { gesture in
sliderMoving = false
updateProgress(x: gesture.location.x, width: geometry.size.width)
seekToProgress(p: progress)
}
)
}
private func updateProgress(x: CGFloat, width: CGFloat) {
let knobWidth: CGFloat = 30
if x < knobWidth / 2 {
progress = TimeInterval(0)
} else if x >= width - knobWidth / 2 {
progress = TimeInterval(100)
} else {
let x2 = x - knobWidth / 2
let width2 = width - knobWidth
progress = TimeInterval(x2 / (width2 / 100))
}
}
唯一的缺点是我们假设旋钮有一个固定的值,但因为我设置滑块高度为30无论如何,它在我的情况下完美地工作。
2条答案
按热度按时间icomxhvb1#
看看这个解决方案是否适合你。正如我在评论中提到的,它基本上完全覆盖了滑块的手势阅读器。为了得到宽度,我使用了几何阅读器。你甚至可以使用
.gesture
或者.highPriorityGesture
来代替simultaneousGesture
。此外,根据你放置GeometryReader
的位置,你可能需要使用手势的.local coordinateSpace
。更新以下注解。这可以根据填充修改器和旋钮大小进行调整。根据滑块的设置方式,可能需要进行不同的调整以获得准确的位置。我目前还不知道一种方法来获得滑块的各个部分的确切位置。自定义滑块可以解决此问题。
xcitsw882#
干得好,@Marco Boerner和@Makalele。我今天也遇到了同样的问题,在你的帮助下,我创造了一个更通用的解决方案。在我的特定用例中,我有一个带有自定义DragGesture的Button(用于捕获向下点击和向上点击事件)。当按下按钮时,它会阻止滑块视图更新,因为我的自定义DragGesture正在优先考虑。
关于代码的一些评论:
首先,这里是计算滑块大小的修改器:
接下来,这里是带有自定义手势扩展的Slider,它调用一个函数来计算新的滑块值:
以及计算新值的函数:
也许iOS 17会解决所有这些问题,这样我们就不必创建这些解决方案了。