如果用户将手指从精灵套件中的按钮上移开,如何停止按钮操作?

Posted

技术标签:

【中文标题】如果用户将手指从精灵套件中的按钮上移开,如何停止按钮操作?【英文标题】:How to stop button action if user moves their finger off the button in sprite kit? 【发布时间】:2021-03-27 15:38:08 【问题描述】:
 override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) 
        let touch = touches.first
        let positionInScene = touch!.location(in: self)
        let touchedNode = self.atPoint(positionInScene)
        if let name = touchedNode.name 
            if name == "leftbutton" 
                print("left button stopped")
                touchedNode.run(buttonStoppedPressAction)
                player?.removeAllActions()
            
            
            if name == "rightbutton" 
                print("right button stopped")
                
                touchedNode.run(buttonStoppedPressAction)
                
                player?.removeAllActions()
            


这里我有代码,当用户从按钮上抬起手指时,它会停止动作,但前提是他们在按钮内抬起手指。因此,如果他们按下它并开始在屏幕上的其他位置移动手指,同时持续按下该按钮将不会停止执行其代码。感谢您的帮助。

【问题讨论】:

【参考方案1】:

基本上,您应该检查触地时的触摸位置,并与触地时的位置进行比较。如果触摸不再在您的按钮区域内,您将取消所有效果。

不过,首先要说一点。看起来您正在处理 SKScene 级别的按钮逻辑,这是教程经常告诉您的。但是,这可能不是最好的方法。这里的风险,除了 SKScene 的杂乱无章之外,还来自处理多个对象以及它们如何对触摸事件做出反应,以及多点触控带来的额外复杂性(如果允许的话)。

几年前,当我开始使用 SpriteKit 时,我觉得这是一个巨大的痛苦。所以我创建了一个按钮类来独立处理所有的触摸逻辑(并在需要发生某些事情时将信号发送回父级)。好处:没有不必要的混乱,区分对象没有问题,能够确定每个节点的多点触控允许。

我在课堂上查看触摸是否在触摸之前没有离开按钮的操作是存储按钮区域的大小(作为对象的参数)和其中的触摸位置。简单简单。

事实上,Apple 并没有默认提供一个基本的 SKButton 类,这让我永远感到困惑。无论如何,我想你可能想考虑一下。至少对我来说,它每天都节省了很多时间。而且我已经发布了多个具有相同自定义按钮类的成功应用程序。

编辑:下面是我的准系统 Button 类。

import SpriteKit

class Button: SKNode 
    
    private var background: SKSpriteNode?
    private var icon: SKNode?
    
    private var tapAction: () -> Void = 
    
    override init() 
        super.init()
        
        isUserInteractionEnabled = true
    
    
    required init?(coder aDecoder: NSCoder) 
        super.init(coder: aDecoder)
        
        isUserInteractionEnabled = true
    
    
    // MARK: Switches
    
    public func switchButtonBackground(buttonBackgroundSize: CGSize, buttonBackgroundColor: SKColor) 
        background = SKSpriteNode(color: buttonBackgroundColor, size: buttonBackgroundSize)
        addChild(background!)
    
    
    public func switchButtonIcon(_ buttonIcon: SKNode) 
        if icon != nil 
            icon = nil
        
        
        icon = buttonIcon
        addChild(icon!)
    
    
    public func switchButtonTapAction(_ buttonTapAction: @escaping () -> Void) 
        tapAction = buttonTapAction
    
    
    // MARK: Touch events
    
    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) 
        tapAction()
    

然后您创建 Button 对象,首先启动它,使用大小和颜色为其分配背景,然后为其分配一个图标,为其分配一个在点击时运行的功能,最后将其作为子项添加到场景中。

let icon = SKNode()
let size = CGSize(width: 20.0, height: 20.0)

let button = Button()
button.switchButtonBackground(buttonBackgroundSize: size, buttonBackgroundColor: .clear)
button.switchButtonIcon(icon)
button.switchButtonTapAction(buttonPressed)
addChild(button)

背景定义了按钮的触摸区域,您可以为其设置颜色或将其确定为 .clear。该图标应该在按钮顶部包含您想要的任何文本或图像。只需将它们打包成一个 SKNode 就可以了。如果你想运行一个带参数的函数作为点击动作,你可以做一个代码块。

希望对您有所帮助!如果您需要任何进一步的帮助,请告诉我:)。

【讨论】:

您好,谢谢您的回复。我看过一些使用按钮类的教程,但并不真正知道它们的含义,我很新。如果您可以发送它的准系统,那将非常有帮助,也许如果您有时间只需解释其中发生的事情。 我在上面的回复中添加了我的 Button 类。 非常感谢,我有点明白了。你能写一个你使用它的示例按钮,这样我可以参考它,如果它不是太麻烦,但如果你不能不担心。 嗯,这个例子在上面,在那边。只需为 Button 类创建一个新的 Swift 文件,复制粘贴主要代码并将其放入项目中。然后在您的场景文件中,只需按照我的回复中所述启动按钮。它应该出现:)。我猜你只是在场景中添加了一个名为 buttonPressed (或其他)的函数,并且应该可以工作。 感谢大家的帮助。

以上是关于如果用户将手指从精灵套件中的按钮上移开,如何停止按钮操作?的主要内容,如果未能解决你的问题,请参考以下文章

检测用户何时将手指从 UIScrollView 上移开

css 兼容性问题

无需从屏幕上移开手指即可触摸按钮

除非之前按下,否则按下运行按钮不会提高速度

在精灵套件中发生碰撞时停止对象

动画视图并中途停止