我有一个 SceneKit SCNView
,我想在上面附加一个平移手势识别器。这将执行一个 hitTest
来确定用户是否触摸了我场景中的特定对象。但是,如果此点击测试失败(用户没有特别触摸任何东西),那么我想将该触摸传递给默认相机 Controller 。
目前,添加我自己的平移手势识别器似乎会覆盖默认相机 Controller 并阻止其工作。
let scnView = SCNView()
// Configure scnView with my geometry etc
// ...
let panGesture = UIPanGestureRecognizer(target: context.coordinator,
action: #selector(panned))
scnView.addGestureRecognizer(panGesture)
scnView.allowsCameraControl = true
目前我的手势识别器是这样开始的:
@objc func panned(gesture: UIPanGestureRecognizer) {
let sceneView : SCNView = gesture.view as! SCNView
let point = gesture.location(in: sceneView)
switch gesture.state {
case .began:
guard let hitNodeResult = sceneView.hitTest(point, options: [:]).first else { return }
// Rather than just 'return' I suspect I want to do something here...
// ....
}
最佳答案
三件事最终帮助我解决了这个问题:
1。同时处理两个平移手势
首先,我必须在我自己的平移手势上添加一个手势识别器委托(delegate):
myPanGesture.delegate = self
像这样的委托(delegate)方法:
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true;
}
2。要求我们的平移手势在相机启动前失败
接下来我找到了控制相机的内置平移手势识别器,并告诉它需要我的平移手势失败才能起作用:
let panGestures = scnView.gestureRecognizers!.filter { $0 is UIPanGestureRecognizer } as! [UIPanGestureRecognizer]
if (!panGestures.isEmpty) {
let cameraPanGesture = panGestures.first!
cameraPanGesture.require(toFail: myPanGesture)
}
3。将失败的 HitTest 视为手势识别器“失败”
@objc func panned(gesture: UIPanGestureRecognizer) {
let sceneView : SCNView = gesture.view as! SCNView
let point = gesture.location(in: sceneView)
switch gesture.state {
case .began:
guard let hitNodeResult = sceneView.hitTest(point, options: [:]).first else {
// Cancel the gesture so that the camera pan kicks in
gesture.state = .failed
return
}
// .....
然后,嘿,很快,它起作用了!现在,您可以通过平移场景中的对象来旋转场景,或者在点击对象时平移对象。
关于ios - 如果 HitTest 失败,则将平移手势传递给默认相机 Controller ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59510398/