如何为SKSpriteNode添加UITapGestureRecognizer?已尝试但未生效
为SKSpriteNode添加UITapGestureRecognizer的正确方法
你的代码失效的核心问题是用错了手势添加对象——SKSpriteNode没有inputView属性,这是UIKit控件的专属属性,所以wayang.inputView?.addGestureRecognizer(wayangTap)这行代码根本不会执行,手势自然无法触发。下面给你两种可行的解决方法:
方法一:给SKView添加手势,判断点击范围
把手势识别器添加到当前场景的SKView上,通过坐标转换判断点击位置是否落在目标节点内:
override func didMove(to view: SKView) { wayang = SKSpriteNode(imageNamed: "WayangPlayGuy") wayang.size = CGSize(width: 200, height: 200) wayang.position = CGPoint(x: 87, y: 101) wayang.isUserInteractionEnabled = true addChild(wayang) // 创建手势并绑定到SKView let wayangTap = UITapGestureRecognizer(target: self, action: #selector(didTapWayang)) view.addGestureRecognizer(wayangTap) } @objc func didTapWayang(_ gesture: UITapGestureRecognizer) { guard let skView = gesture.view as? SKView else { return } // 将手势的屏幕坐标转换为场景内的坐标 let tapPosition = skView.convert(gesture.location(in: skView), to: self) // 判断点击位置是否在wayang节点范围内 if wayang.contains(tapPosition) { // 这里添加点击后的业务逻辑 print("Wayang被点击") } }
方法二:重写SKSpriteNode的触摸方法(原生SpriteKit方式)
创建自定义的SKSpriteNode子类,重写触摸事件方法,这种方式更贴合SpriteKit的设计逻辑:
// 自定义可点击的SpriteNode子类 class TapableWayangNode: SKSpriteNode { override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { // 这里直接写点击触发的逻辑 print("Wayang节点被点击") // 如果需要通知父场景,可通过代理或通知中心实现 } }
在场景中使用这个子类:
override func didMove(to view: SKView) { let wayang = TapableWayangNode(imageNamed: "WayangPlayGuy") wayang.size = CGSize(width: 200, height: 200) wayang.position = CGPoint(x: 87, y: 101) wayang.isUserInteractionEnabled = true // 必须开启用户交互 addChild(wayang) }
注意事项
- 两种方法都必须确保
isUserInteractionEnabled设置为true,否则节点不会响应任何触摸操作 - 方法一适合场景中有多个可点击节点的情况,统一管理手势;方法二更适合单个节点的独立交互逻辑
内容的提问来源于stack exchange,提问作者Farhandika
相关产品推荐
相关产品推荐

