Reputation: 5617
In Swift and SpriteKit, you can designate an object as "isUserInteractionEnabled=false". Confusingly, this does not mean that the object will ignore touches and let those touches pass through to nodes below it.
The way I built SpriteKit apps it is very common for me to create a node (like a SKShapeNode or an SKSpriteNode) and then slap a label on it. What I want is for the label to ignore touches and let those touches pass through to the node behind it but I am failing to understand how this is done, if "isUserInteractionEnable" is not the ticket.
Any suggestions? Here is a sample label that receives touches but should not:
class MenuButton: SKShapeNode {
/* The MenuBar will have as children nine buttons of two types. Dialog Springers and SubMenu Droppers */
// MARK: - Class Variables
var title = "Button"
var menu = SKShapeNode()
let buttonLabel = SKLabelNode(fontNamed: devFont4)
init(title: String)
{
super.init()
isUserInteractionEnabled = true
self.title = title
self.name = "\(title) Menu Button"
let btnLen = title.count * 10 + 16
let menuSize = CGSize(width: btnLen, height: 32)
menu = SKShapeNode(rectOf: menuSize)
addChild(menu)
menu.fillColor = .clear
menu.strokeColor = .clear
menu.lineWidth = 0
menu.zPosition = 501
// Add Label
let letterHeight: CGFloat = 22
buttonLabel.text = title
buttonLabel.name = "\(title) Label"
buttonLabel.fontSize = letterHeight
buttonLabel.fontColor = .black
buttonLabel.zPosition = 502
buttonLabel.position = CGPoint(x: 0, y: Int(-letterHeight/2) + 2)
buttonLabel.isUserInteractionEnabled = false
addChild(buttonLabel)
}
}
Upvotes: 1
Views: 300
Reputation: 16827
In Swift and SpriteKit, you can designate an object as "isUserInteractionEnabled=false". Confusingly, this does not mean that the object will ignore touches and let those touches pass through to nodes below it.
That is incorrect, isUserInteractionEnabled=false means that the object will ignore touches and let touches pass through it.
You have a completely different problem. In your code, your main menu does not have a size, so it is passing through your label, inner menu node, and outer menu node, hitting your scene.
Upvotes: 1
Reputation: 11531
There is only one first responder to receive the touches event. The isUserInteractionEnabled
is used to decide which one is called first even Both are enabled. Play the following codes and you can have a feeling what's going on.
class Button: SKLabelNode{
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
print("button")
}
}
class MenuButton: SKShapeNode {
/* The MenuBar will have as children nine buttons of two types. Dialog Springers and SubMenu Droppers */
// MARK: - Class Variables
var title = "Button"
var menu = SKShapeNode()
let buttonLabel = Button.init()
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
print("hit")
}
init(title: String)
{
super.init()
isUserInteractionEnabled = true
self.title = title
self.name = "\(title) Menu Button"
let btnLen = title.count * 10 + 16
let menuSize = CGSize(width: btnLen, height: 32)
menu = SKShapeNode(rectOf: menuSize)
addChild(menu)
menu.fillColor = .green
menu.strokeColor = .clear
menu.lineWidth = 0
menu.zPosition = 501
menu.isUserInteractionEnabled = false
// Add Label
let letterHeight: CGFloat = 122
buttonLabel.text = title
buttonLabel.name = "\(title) Label"
buttonLabel.fontSize = letterHeight
buttonLabel.fontColor = .black
buttonLabel.zPosition = 502
buttonLabel.position = CGPoint(x: 0, y: Int(-letterHeight/2) + 2)
buttonLabel.isUserInteractionEnabled = true
addChild(buttonLabel)
self.path = UIBezierPath.init(rect:self.calculateAccumulatedFrame()).cgPath
self.fillColor = UIColor.red
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Upvotes: 1