Ios 如果命中测试失败,则将平移手势传递给默认摄影机控制器
我有一个SceneKitIos 如果命中测试失败,则将平移手势传递给默认摄影机控制器,ios,swift,scenekit,Ios,Swift,Scenekit,我有一个SceneKitSCNView,我希望在其中附加一个平移手势识别器。这将执行一个hitTest,以确定用户是否触摸了我场景中的特定对象。但是,如果这个命中测试失败(用户没有特别触摸任何东西),那么我希望将该触摸传递到默认的相机控制器 目前,添加我自己的平移手势识别器似乎会覆盖默认的相机控制器,并阻止它工作 let scnView = SCNView() // Configure scnView with my geometry etc // ... let panGesture = U
SCNView
,我希望在其中附加一个平移手势识别器。这将执行一个hitTest
,以确定用户是否触摸了我场景中的特定对象。但是,如果这个命中测试失败(用户没有特别触摸任何东西),那么我希望将该触摸传递到默认的相机控制器
目前,添加我自己的平移手势识别器似乎会覆盖默认的相机控制器,并阻止它工作
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.同时处理两个平移手势 首先,我必须在自己的平移手势上添加手势识别器代理:
myPanGesture.delegate = self
使用这样的委托方法:
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.将失败的命中测试视为手势识别器“失败”
然后,嘿,普雷斯托,它起作用了!现在,您可以通过平移远离场景中的对象来旋转场景,或者在单击对象时平移对象。最后有三件事帮助我解决了这个问题: 1.同时处理两个平移手势 首先,我必须在自己的平移手势上添加手势识别器代理:
myPanGesture.delegate = self
使用这样的委托方法:
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.将失败的命中测试视为手势识别器“失败”
然后,嘿,普雷斯托,它起作用了!现在,您可以通过平移远离场景中的对象来旋转场景,或者在点击对象时平移对象。只是为了澄清@andygeer出色的解决方案中的所有代码可以放在哪里
class GameViewController: UIViewController, UIGestureRecognizerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let scnView = SCNView()
// Configure scnView with my geometry etc
// ...
let myPanGesture = UIPanGestureRecognizer(target: self,
action: #selector(panned))
myPanGesture.delegate = self
scnView.addGestureRecognizer(myPanGesture)
scnView.allowsCameraControl = true
let panGestures = scnView.gestureRecognizers!.filter { $0 is UIPanGestureRecognizer } as! [UIPanGestureRecognizer]
if (!panGestures.isEmpty) {
let cameraPanGesture = panGestures.first!
cameraPanGesture.require(toFail: myPanGesture)
}
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return 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 {
// Cancel the gesture so that the camera pan kicks in
gesture.state = .failed
return
}
// .....
}
}
}
只是为了澄清@andygeer出色的解决方案中的所有代码可以放在哪里
class GameViewController: UIViewController, UIGestureRecognizerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let scnView = SCNView()
// Configure scnView with my geometry etc
// ...
let myPanGesture = UIPanGestureRecognizer(target: self,
action: #selector(panned))
myPanGesture.delegate = self
scnView.addGestureRecognizer(myPanGesture)
scnView.allowsCameraControl = true
let panGestures = scnView.gestureRecognizers!.filter { $0 is UIPanGestureRecognizer } as! [UIPanGestureRecognizer]
if (!panGestures.isEmpty) {
let cameraPanGesture = panGestures.first!
cameraPanGesture.require(toFail: myPanGesture)
}
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return 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 {
// Cancel the gesture so that the camera pan kicks in
gesture.state = .failed
return
}
// .....
}
}
}
您在哪里添加了第2点代码?@PrashantTukadiya当我设置
myPanGesture
时,我的泛手势我指的是在这里的哪个函数中func gestureRecognizer(_gestureRecognizer:UIGestureRecognizer,应该与其他gestureRecognizer:UIGestureRecognizer)->Bool{
?@PrashantTukadiya这是一个手势代表的方法。在我的“第1点”下我将其委托设置为“self”-因此您可以将其定义为创建手势的类上的一个方法。您可以轻松地将委托设置为您喜欢的任何其他对象,并将其定义为该对象上的一个方法,而不是添加了第2点代码?@PrashantTukadiya,因为我正在设置myPanGesture
,我的泛指这里的操作func GestureRecognitizer(uGestureRecognitizer:UIGestureRecognitizer,应该与其他GestureRecognitizer:UIGestureRecognitizer同时识别)->Bool{
?@PrashantTukadiya这是手势代理上的一个方法。在我的“点1”下我将其委托设置为“self”-因此您可以将其定义为创建手势的类上的方法。您可以轻松地将委托设置为您喜欢的任何其他对象,并将其定义为该类上的方法