             return
         }
         
+        let inverted = renderer.node().place.invert()!
+        
+        touchesOfNode.keys.forEach { currentNode in
+            guard let touches = touchesOfNode[currentNode] else {
+                return
+            }
+            
+            var points = [TouchPoint]()
+            for touch in touches {
+                let location = touch.location(in: self)
+                let loc = location.applying(RenderUtils.mapTransform(inverted))
+                let id = unsafeBitCast(Unmanaged.passUnretained(touch).toOpaque(), to: Int.self)
+                let point = TouchPoint(id: id, location: Point(x: Double(loc.x), y: Double(loc.y)))
+                points.append(point)
+            }
+            
+            let touchEvent = TouchEvent(node: currentNode, points: points)
+            node.handleTouchMoved(touchEvent)
+        }
+    }
+    
+    open override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
+        touchesEnded(touches: touches, event: event)
+    }
+    
+    open override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
+        touchesEnded(touches: touches, event: event)
+    }
+    
+    private func touchesEnded(touches: Set<UITouch>, event: UIEvent?) {
+        if !self.node.shouldCheckForReleased() {
+            return
+        }
+        
+        guard let renderer = renderer else {
+            return
+        }
+        
         for touch in touches {
             let location = touch.location(in: self)
-            
-            
             let inverted = renderer.node().place.invert()!
             let loc = location.applying(RenderUtils.mapTransform(inverted))
             

                let inverted = renderer.node().place.invert()!
                let loc = location.applying(RenderUtils.mapTransform(inverted))
                
                var id = unsafeBitCast(Unmanaged.passUnretained(touch).toOpaque(), to: Int.self)
                let point = TouchPoint(id: id, location: Point(x: Double(loc.x), y: Double(loc.y)))
                let touchEvent = TouchEvent(node: node, points: [point])
                
                var parent: Node? = node
                while parent != .none {
                    
                    if parent!.shouldCheckForPressed() {
                        touchesMap[touch]?.append(parent!)
                        parent!.handleTouchPressed(touchEvent)
                    }


                let point = TouchPoint(id: id, location: Point(x: Double(loc.x), y: Double(loc.y)))
                let touchEvent = TouchEvent(node: node, points: [point])
                
                node.handleTouchReleased(touchEvent)
                if let index = touchesOfNode[node]?.index(of: touch) {
                    touchesOfNode[node]?.remove(at: index)
                    if let count = touchesOfNode[node]?.count, count == 0 {
                        touchesOfNode.removeValue(forKey: node)
                    }
                }
            }
            
            touchesMap.removeValue(forKey: touch)
