Last active
July 11, 2016 12:37
-
-
Save zmeyc/58d4c661ff3bb0d35db8 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Original Objective C version: https://gist.github.com/bobmoff/7110052 | |
// | |
// Fix SpriteKit's SKNode bug on iOS 7 & 8: nodes capture touch events | |
// even when userInteractionEnabled is false and the nodes are hidden. | |
// | |
// Details: | |
// http://stackoverflow.com/questions/19511334/sprite-with-userinteractionenabled-set-to-yes-does-not-receive-touches-when-cove | |
// | |
// How to use: | |
// Use SKSceneWithUserInteractionBugfix class in place of SKScene. | |
// | |
import SpriteKit | |
extension SKNode { | |
func nodeDepthPriority() -> String { | |
var code = "" | |
var currentNode = self | |
while let parent = currentNode.parent { | |
var idx = 0 | |
for obj in parent.children { | |
if obj == currentNode { | |
code = NSString(format: "%03d%@", idx, code) as String | |
break | |
} | |
++idx | |
} | |
currentNode = parent | |
} | |
return code | |
} | |
} | |
extension SKScene { | |
func nodeWithHighestPriority(touches: NSSet) -> SKNode? { | |
// Only allow touches to be receieved by nodes with userInteractionEnabled, and only the one with the highest touch priority | |
guard let touch = touches.anyObject() else { return nil } | |
let touchLocation = touch.locationInNode(self) | |
let touchedNodes = nodesAtPoint(touchLocation) | |
var nodeToTouch: SKNode! | |
for node in touchedNodes { | |
if node.userInteractionEnabled && !node.hidden && node.alpha > 0 { | |
if nodeToTouch == nil { | |
nodeToTouch = node | |
} else if node.parent == nodeToTouch.parent && node.zPosition > nodeToTouch.zPosition { | |
nodeToTouch = node | |
} else if node.parent == nodeToTouch.parent && node.zPosition == nodeToTouch.zPosition && nodeToTouch.nodeDepthPriority().compare(node.nodeDepthPriority()) == .OrderedAscending { | |
nodeToTouch = node | |
} else if node.parent != nodeToTouch.parent && nodeToTouch.nodeDepthPriority().compare(node.nodeDepthPriority()) == .OrderedAscending { | |
nodeToTouch = node | |
} | |
} | |
} | |
return nodeToTouch | |
} | |
} | |
public class SKSceneWithUserInteractionBugfix: SKScene { | |
public override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { | |
let nodeToTouch = nodeWithHighestPriority(touches) | |
nodeToTouch?.touchesBegan(touches, withEvent: event) | |
} | |
public override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) { | |
let nodeToTouch = nodeWithHighestPriority(touches) | |
nodeToTouch?.touchesEnded(touches, withEvent: event) | |
} | |
public override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) { | |
guard let touches = touches else { return } | |
let nodeToTouch = nodeWithHighestPriority(touches) | |
nodeToTouch?.touchesCancelled(touches, withEvent: event) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment