从另一个类调用选择器的 UIGestureRecognizer

Posted

技术标签:

【中文标题】从另一个类调用选择器的 UIGestureRecognizer【英文标题】:UIGestureRecognizer with selector being called from another class 【发布时间】:2017-12-31 03:00:16 【问题描述】:

我有两个类都添加UIPinchGestureRecognizer 并使用选择器来处理响应手势的代码。注意:手势识别器委托可能与此问题无关,但我将其包含在代码中以防万一。

class GameScene: SKScene, UIGestureRecognizerDelegate 

    override func didMove(to view: SKView) 
        let pinchGestureRecognizer = UIPinchGestureRecognizer(target: self, action: #selector(handlePinchFrom))
        pinchGestureRecognizer.delegate = self
        self.view!.addGestureRecognizer(pinchGestureRecognizer)
    

    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool 
        return true
    

    @objc func handlePinchFrom(_ rec: UIPinchGestureRecognizer) 
        // This method should only be called when pinching in GameScene scene.
    



class Level1: SKScene, UIGestureRecognizerDelegate 

    // Same code here as in GameScene class.

    @objc func handlePinchFrom(_ rec: UIPinchGestureRecognizer) 
        // This method should only be called when pinching in Level scene.
    

GameScene 中,handlePinchFrom 方法被正常调用。在用户从GameScene 转换到Level1 场景后,Level1 中的handlePinchFrom 方法被正常调用。然而,GameScene 中的 handlePinchFrom 方法在 Level1 中执行捏合手势时仍然会被调用,即使 GameScene 不再出现在调试视图层次结构中。

同样,如果用户随后离开Level1 并转换回GameScene,当您在GameScene 中执行捏合手势时,来自Level1handlePinchFrom 方法也会被调用。

我猜这可能是由于两个选择器使用了相同的名称 (handlePinchFrom)。但是我尝试给其中一个选择器起一个不同的名称,但当我希望只调用其中一个时,它们仍然会被调用。

有谁知道为什么在加载Level1 后仍然会调用来自GameScenehandlePinchFrom 方法,即使程序不再运行GameScene 类?

【问题讨论】:

"有谁知道为什么 GameScene 中的 handlePinchFrom 方法仍然会被调用" 这显然是因为你在视图控制器中添加了一个观察者并且没有移除它。 @ElTomato 我理解我使用#selector 是一种让Objective-C 功能在Swift 中工作的方法。我承认我对 Obj-C 不太熟悉。我假设一旦我离开场景,选择器就会被移除。离开场景前是否需要明确移除选择器? 手势识别器被添加到view 并且您在Level1 场景中使用相同的视图。您需要在willMove(from view:) 中删除带有view.removeGestureRecognizer(...) 的旧识别器 【参考方案1】:

感谢 0x141E 的建议,我修复了我的代码。请参阅下面的更新代码。

我设置了手势识别器并在didMove(to view:) 中获取了对它的引用。然后我使用引用将其从willMove(from view:) 的场景视图中删除。

现在,在我的应用离开游戏场景后,不再调用手势识别器。

class GameScene: SKScene 
    var pinchGrRef: UIPinchGestureRecognizer?

    override func didMove(to view: SKView) 
        let pinchGestureRecognizer = UIPinchGestureRecognizer(target: self, action: #selector(handlePinchFrom))
        self.view!.addGestureRecognizer(pinchGestureRecognizer)
        self.pinchGrRef = pinchGestureRecognizer
    

    @objc func handlePinchFrom(_ rec: UIPinchGestureRecognizer) 
        // Respond to pinch gesture
    

    override func willMove(from view: SKView) 
        if pinchGrRef != nil  self.view!.removeGestureRecognizer(pinchGrRef!) 
    

【讨论】:

以上是关于从另一个类调用选择器的 UIGestureRecognizer的主要内容,如果未能解决你的问题,请参考以下文章

如何从另一个类中调用 onItemClick 方法?

如何检查是否从另一个类中检查了RadioButton?

如何从另一个类调用@selector 方法

如何从另一个类调用方法函数?

引导日期选择器从另一个日期选择器更改 minDate/startDate

如何从另一个类调用 QMainWindow 组件?