Overlay to block touches (SKSpriteNode/SKShapeNode alpha problem)

Hi!


I moved to SpriteKit from Cocos2d, so I'm currently converting my component classes into SpriteKit and Swift. One of these classes is Overlay, which blocks any touches underneath it. The idea is that I can throw the Overlay object for example in-between scene objects and a popup. I find it's a much more secure and flexible way to block touches than having some switch in the code disabling actions, and what not. In addition it also optionally provides a fading color layer if you want one.


The conversion was pretty easy, but I've run into an issue with touch detection. For the class I'm subclassing SKNode and for the color layer I'm using either a SKSpriteNode or SKShapeNode (tried both). In Cocos2d CCNode had a content size, so it was easy to just define its frame and the node would respond to touches automatically. In SpriteKit SKNodes don't have a size, so I think it instead responds to touches on any nodes that it contains. This in itself is not so bad, since I do use a full-screen SKSpriteNode or SKShapeNode, which should handle the touch detection.


The problem I have is that when the SKSpriteNode/SKShapeNode has an alpha of 0.0, it does still respond to touches, but it doesn't block them. I need the alpha 0.0 to block touches in cases where the user shouldn't see the overlay. I guess I could just make the alpha something like 0.00001, but I would like a cleaner solution. Is there a way to make SKSpriteNode or SKShapeNode block touches from nodes underneath even when the alpha is 0.0?


Here blockTouches() will indeed make the overlay react to touches for a duration, but it won't swallow them (if alpha is turned up, too, then it works):


import SpriteKit


class Overlay: SKNode {
   
    var background: SKShapeNode?
    var opacity: CGFloat?
   
    convenience init(backgroundColor: SKColor, backgroundOpacity: CGFloat) {
        self.init()
       
        background = SKShapeNode(rectOfSize: CGSize(width: UIScreen.mainScreen().bounds.size.width, height: UIScreen.mainScreen().bounds.size.height))
        background?.position = CGPoint(x: UIScreen.mainScreen().bounds.size.width * 0.5, y: UIScreen.mainScreen().bounds.height * 0.5)
        background?.lineWidth = 0
        background?.fillColor = backgroundColor
        background?.alpha = 0.0
        background?.zPosition = 10
        self.addChild(background!)
       
        opacity = backgroundOpacity
    }
   
    override init() {
        super.init()
    }
   
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
   
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        print("Overlay touched!")
    }
   
    func blockTouchesForDuration(duration: Double) {
        userInteractionEnabled = true
        self.runAction(SKAction.sequence([SKAction.waitForDuration(duration), SKAction.runBlock({
             self.userInteractionEnabled = false
        })]))
    }
}
Overlay to block touches (SKSpriteNode/SKShapeNode alpha problem)
 
 
Q