以编程方式制作的按钮与 viewController 的手势识别器冲突

Posted

技术标签:

【中文标题】以编程方式制作的按钮与 viewController 的手势识别器冲突【英文标题】:Programmatically made buttons conflict with viewController’s gesture recognizers 【发布时间】:2018-10-02 02:49:48 【问题描述】:

参考我上一个问题:

Spritekit: passing from UIButtons to buttons as SKSpriteNode

我正在开发一个 SpriteKit 游戏:用户可以在屏幕上点击和滑动以在场景中移动精灵,为此我在我的 ViewController 中添加了手势识别器。 然后我创建了一个 HUD 以保留 4 个以编程方式制作的按钮,用户可以使用这些按钮将其他精灵添加到场景中。 我希望我的按钮在按下时淡出并缩放一点,然后返回到原始状态,但似乎它们与 viewController 的手势识别器冲突:按钮淡出并缩小,但它们保持在那个状态,不要回到正常状态。 我能做些什么? 这是 Button 类:

import SpriteKit
protocol ButtonDelegate: NSObjectProtocol 
    func buttonClicked(sender: Button)

class Button: SKSpriteNode 
    weak var delegate: ButtonDelegate!
    var buttonTexture = SKTexture()
    init(name: String) 
        buttonTexture = SKTexture(imageNamed: name)
        super.init(texture: buttonTexture, color: .clear, size: buttonTexture.size())
        self.isUserInteractionEnabled = true

required init?(coder aDecoder: NSCoder) 
    fatalError("init(coder:) has not been implemented")

var touchEndedCallback: (() -> Void)?
weak var currentTouch: UITouch?
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) 
    if isUserInteractionEnabled 
        setScale(0.9)
        self.alpha = 0.5
        if let currentTouch = touches.first 
            let touchLocation = currentTouch.location(in: self)
            for node in self.nodes(at: touchLocation) 
                delegate?.buttonClicked(sender: self)
            
        
    


override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) 
    setScale(1.0)
    self.alpha = 1.0
    touchEndedCallback?()
    print("tapped!")


这是我在 View Controller 中使用的代码:

class ViewController: UIViewController, UIGestureRecognizerDelegate 
    override func viewDidLoad() 
        super.viewDidLoad()
        let skView = view as! SKView
        skView.isMultipleTouchEnabled = false
        skView.presentScene(scene)
    @IBAction func didTap(_ sender: UITapGestureRecognizer) 
        game.myCode
    
    @IBAction func didPan(_ sender: UIPanGestureRecognizer) 
        let currentPoint = sender.translation(in: self.view)
        if let originalPoint = panPointReference 
            if abs(currentPoint.x - originalPoint.x) > (SquareSize * 0.9) 
                if sender.velocity(in: self.view).x > CGFloat(0) 
                    //game.myCode
                    panPointReference = currentPoint
                 else 
                    //game.myCode
                    panPointReference = currentPoint
                
            
         else if sender.state == .began 
            panPointReference = currentPoint
        
    
    @IBAction func didSwipe(_ sender: UISwipeGestureRecognizer) 
        //game.myCode
    
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive shouldReceiveTouch: UITouch) -> Bool 
        if UITouch .isKind(of: Button.self) 
            return false
        
        return true
    
    func buttonClicked(sender: Button) 
        //myCode
    

【问题讨论】:

【参考方案1】:

解决了! 好的,比我想象的要简单。 (我休息了)。 - 我删除了 UIgestures 并以编程方式添加它们; - 在我的 GameScene 的 touchesEnded 方法中,我创建了一个条件来检查我的哪个节点被触摸了。 - 在视图控制器中,我添加了 gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:) 方法,以避免与附加到不同视图的手势识别器发生冲突(我的节点位于两个不同的视图中):

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool 
    if gestureRecognizer.view != otherGestureRecognizer.view 
        return false
    
    return true

我希望这会有所帮助……

【讨论】:

【参考方案2】:

我认为它们不会干扰 View Controller 的内置手势识别器,因为您没有添加自己的任何手势,您只是覆盖了 touchesBegin 和 touchesEnded。

“点击”会打印出来吗?

有可能 touchesEnd() 没有被调用,请尝试实现 touchesCancelled() 并查看它是否被调用。

【讨论】:

不,touchesEnd() 没有被调用,“tapped”没有被打印出来......但在将手势识别器添加到 GameViewController 之前,一切正常。添加它们后,我的按钮停止工作。如果我按下一个按钮,它会淡出并缩放,但会停留在那个状态,不会回到正常状态。 我在您发布的代码中没有看到任何手势识别器。 昨天我更改并添加了代码:平移、点击和手势识别器应用于视图,因此用户可以在其中移动精灵。但是在我添加它们之后,我的按钮停止工作。我真的不知道如何解决这个问题。

以上是关于以编程方式制作的按钮与 viewController 的手势识别器冲突的主要内容,如果未能解决你的问题,请参考以下文章

Swift以编程方式制作宽度百分比

以编程方式使后退按钮转到上一个视图

如何处理以编程方式添加的按钮事件? C#

如何在不制作 IBOutlet 的情况下以编程方式在 Swift 中为 UIView 高度约束设置动画?

在 iOS 中以编程方式使按钮播放声音

有没有办法在Swift中以编程方式设置NSCollectionView?