我想在按钮开始按下时执行一个操作,然后在按钮停止按下时执行。我一直在寻找一个简单的解决方案,但遇到了更复杂的配置。一个非常简单和接近的选项是我从BlueSpud得到的。按钮操作没有使用,所以我尝试了:
struct MyView: View {
@State private var pressing = false
var body: some View {
Text("Button")
.background(self.pressing ? Color.red : Color.blue)
.gesture(DragGesture(minimumDistance: 0.0)
.onChanged { _ in
self.pressing = true
print("Pressing started and/or ongoing")
}
.onEnded { _ in
self.pressing = false
print("Pressing ended")
})
}
}
这段代码的问题在于,如果您在按下时将手指拖出按钮区域,则永远不会调用.onEnded,并且如果没有可靠的事件结束,则解决方案将无法工作。
我也尝试过苹果的composing SwiftUI gestures示例,它提供了对按下和未按下状态的非常一致的控制,但我似乎不知道在哪里插入我的操作:
struct PressedButton: View {
var startAction: ()->Void
var endAction: ()->Void
enum DragState {
case inactive
case pressing
case dragging(translation: CGSize)
var translation: CGSize {
switch self {
case .inactive, .pressing:
return .zero
case .dragging(let translation):
return translation
}
}
var isActive: Bool {
switch self {
case .inactive:
print("DragState inactive but I can't add my action here")
//self.endAction()
return false
case .pressing, .dragging:
return true
}
}
var isDragging: Bool {
switch self {
case .inactive, .pressing:
return false
case .dragging:
return true
}
}
}
@GestureState var dragState = DragState.inactive
var body: some View {
let longPressDrag = LongPressGesture(minimumDuration: 0.1)
.sequenced(before: DragGesture())
.updating($dragState) { value, state, transaction in
switch value {
// Long press begins.
case .first(true):
print("Long press begins. I can add my action here")
self.startAction()
state = .pressing
// Long press confirmed, dragging may begin.
case .second(true, let drag):
//print("Long press dragging")
state = .dragging(translation: drag?.translation ?? .zero)
// Dragging ended or the long press cancelled.
default:
print("Long press inactive but it doesn't get called")
state = .inactive
}
}
.onEnded { _ in
print("Long press ended but it doesn't get called")
}
return Text("Button")
.background(dragState.isActive ? Color.purple : Color.orange)
.gesture(longPressDrag)
}
}
2条答案
按热度按时间k5ifujac1#
一旦原生SwiftUI现在不允许您想要实现的东西,我推荐以下方法,它是有效的、可管理的,因此是可靠的。
演示展示了基于使用
UIGestureRecongnizer
/UIViewRepresentable
的简化代码,可以轻松扩展(例如,如果您想拦截touchesCanceled
,点击计数等)t9aqgxwy2#
不需要UI视图和可表示,
您可以使用内置的SwiftUI isPressed属性来配置Button,如下所示: