我正在 .sheet
上显示相机预览视图。
我需要检测用户的手指何时触摸预览区域以及用户的手指何时离开预览区域。
我找到的唯一解决方案是这个
CameraPreview()
.gesture(DragGesture(minimumDistance: 0)
.onChanged { _ in
// finger touches
}
.onEnded { _ in
// finger leaves
})
但由于此预览显示在工作表上,并且必须通过从上向下拖动工作表来关闭工作表,因此此拖动手势会阻止工作表拖动手势起作用。
有什么想法吗?
注意:我不需要检测拖动。我需要检测视图上的单击,然后在手指离开该视图时接收回调。
答案 0 :(得分:1)
您需要为此使用 UIViewRepresentable
。以下是步骤:
AnyGestureRecognizer
:class AnyGestureRecognizer: UIGestureRecognizer {
var onCallback: () -> Void
var offCallback: () -> Void
init(target: Any?, onCallback: @escaping () -> Void, offCallback: @escaping () -> Void) {
self.onCallback = onCallback
self.offCallback = offCallback
super.init(target: target, action: nil)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
if let touchedView = touches.first?.view, touchedView is UIControl {
state = .cancelled
offCallback()
} else if let touchedView = touches.first?.view as? UITextView, touchedView.isEditable {
state = .cancelled
offCallback()
} else {
state = .began
onCallback()
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
state = .ended
offCallback()
}
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent) {
state = .cancelled
offCallback()
}
}
UIViewRepresentable
视图并将 AnyGestureRecognizer
附加到它:struct GestureView: UIViewRepresentable {
var onCallback: () -> Void
var offCallback: () -> Void
func makeUIView(context: UIViewRepresentableContext<GestureView>) -> UIView {
let view = UIView(frame: .zero)
let gesture = AnyGestureRecognizer(
target: context.coordinator,
onCallback: onCallback,
offCallback: offCallback
)
gesture.delegate = context.coordinator
view.addGestureRecognizer(gesture)
return view
}
func updateUIView(_ uiView: UIView, context: UIViewRepresentableContext<GestureView>) {}
class Coordinator: NSObject {}
func makeCoordinator() -> GestureView.Coordinator {
Coordinator()
}
}
extension GestureView.Coordinator: UIGestureRecognizerDelegate {
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
true
}
}
struct ContentView: View {
var body: some View {
Color.blue
.sheet(isPresented: .constant(true)) {
Color.red
.overlay(
GestureView(onCallback: { print("start") }, offCallback: { print("end") })
)
}
}
}