Search code examples
swiftsprite-kittouchskscenedisabled-input

Turn off touch for whole screen, SpriteKit, how?


I'm trying to temporarily disable touch on the entire screen, despite their being many sprites with touchesBegun onscreen.

I thought, obviously wrongly, turning off touch for the scene would do it:

    scene?.isUserInteractionEnabled = false

But that didn't work, so I tried this, which also didn't work:

    view?.scene?.isUserInteractionEnabled = false

That also didn't work, so I tried this, also from inside the scene:

    self.isUserInteractionEnabled = false

Solution

  • There is no global method to turn off the touch, whatever is at the top of the drawing queue is the first responder.

    You need to iterate through all of your nodes from your scene and turn them off:

    enumerateChildNodesWithName("//*", usingBlock: 
        { (node, stop) -> Void in  
           node.isUserInteractionEnabled = false
        })
    

    Now the problem is turning them back on, if you use this method, you will turn it on for everything, so you may want to adopt a naming convention for all your touchable sprites

    enumerateChildNodesWithName("//touchable", usingBlock: 
        { (node, stop) -> Void in  
           node.isUserInteractionEnabled = true
        })
    

    This will look for any node that has a name that begins with touchable.

    This method involves recursion, so if you have a ton of nodes, it can be slow. Instead you should use an alternative method:

    let disableTouchNode = SKSpriteNode(color:SKColor(red:0.0,green:0.0,blue:0.0,alpha:0.1),size:self.size)
    disableTouchNode.isUserinteractionEnabled = true
    disableTouchNode.zPosition = 99999
    self.addChild(disableTouchNode)
    

    What this does is slap on an almost transparent node on top of all elements the size of the scene. This way when a user touches the screen, this node will absorb it instead of anything else.