【发布时间】:2021-10-23 16:20:19
【问题描述】:
我目前正在尝试构建一个与 SwiftUI 中的 procreate 有点相似的应用程序(当然不那么复杂;))。
我现在最大的问题是导航。我想使用 2 指平移手势在画布上导航。我进行了大量研究,但尚未找到有关如何使用 SwiftUI 手势实现此功能的解决方案。
我当前的解决方案是使用带有附加手势侦听器的 UIViewRepresentable。不幸的是,这会破坏子视图中的所有手势识别器(其中很多,我都需要它们。
目前的实现是这样的:
struct TwoFingerNavigationView: UIViewRepresentable {
var draggedCallback: ((CGPoint) -> Void)
var dragEndedCallback: (() -> Void)
class Coordinator: NSObject {
var draggedCallback: ((CGPoint) -> Void)
var dragEndedCallback: (() -> Void)
init(draggedCallback: @escaping ((CGPoint) -> Void),
dragEndedCallback: @escaping (() -> Void)) {
self.draggedCallback = draggedCallback
self.dragEndedCallback = dragEndedCallback
}
@objc func dragged(gesture: UIPanGestureRecognizer) {
if gesture.state == .ended {
self.dragEndedCallback()
} else {
self.draggedCallback(gesture.translation(in: gesture.view))
}
}
}
func makeUIView(context: UIViewRepresentableContext<TwoFingerNavigationView>) -> TwoFingerNavigationView.UIViewType {
let view = UIView(frame: .zero)
let gesture = UIPanGestureRecognizer(target: context.coordinator,
action: #selector(Coordinator.dragged))
gesture.minimumNumberOfTouches = 2
gesture.maximumNumberOfTouches = 2
view.addGestureRecognizer(gesture)
return view
}
func makeCoordinator() -> TwoFingerNavigationView.Coordinator {
return Coordinator(draggedCallback: self.draggedCallback,
dragEndedCallback: self.dragEndedCallback)
}
func updateUIView(_ uiView: UIView,
context: UIViewRepresentableContext<TwoFingerNavigationView>) {
}
}
用法如下:
ZStack {
OtherView()
.gesture() // This will break with this "hack"
TwoFingerNavigationView(draggedCallback: { translation in
var newLocation = startLocation ?? location
newLocation.x += (translation.x / scale)
newLocation.y += (translation.y / scale)
self.location = newLocation
}, dragEndedCallback: {
startLocation = location
})
}
有没有人知道如何使用 SwiftUI 手势识别器复制该功能,或者使其与 UIKit 实现一起使用而不会破坏所有孩子的手势?
非常感谢任何帮助和指点!
【问题讨论】:
标签: swift swiftui uikit gesture uipangesturerecognizer