UIView above presented SKScene - Why are touches always going through to the scene?

Viewed 412

I have a confusing situation. First, here's the code:

class MyView: SKView {
    ...
    public override func awakeFromNib() {
        super.awakeFromNib()
        let gameScene = MyGameScene(...)
        // ...
        presentScene(gameScene)

        let view = UIView()
        view.frame = bounds
        view.isUserInteractionEnabled = true
        addSubview(view)
    }
    ...
}

class MyGameScene: SKScene {
    ...
    public override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        print("touch received")
    }
    ...
}

I have a SKView that's presenting a SKScene. After presenting it, I add a UIView that's filling the screen. However, when I start the app and tap on the screen, "touch received" is printed, which means the touch got through to the scene, which should be behind the view. Why is that?

And what can I do to prevent it?

I also tried adding a gesture recogniser to the view. It doesn't prevent the issue, though (even though I set cancelsTouchesInView to true)

Thanks for any help.

2 Answers

Seems you're trying to achieve some kind of a HUD. SceneKit is not pure UIKit so you'll need to adapt your approach - some ideas:

Your issue gets fixed if you add the view to the superview of the SKView (i.e add it to the presenting view controller).

So you can try doing something along these lines:

let view = UIView()
view.frame = bounds
view.isUserInteractionEnabled = true
superview?.addSubview(view)

Alternatively you can add it to the window, but this is not really recommended.

Related