1

I'm trying to draw simple line from the point I started to tap and hold to the point I move my finger to. So it's always a simple line with starting and ending point. I tried different tutorials, but it draws nothing and I do not get any errors.

This is my code within GameScene.swift

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
   /* Called when a touch begins */

    if let touch = touches.first {
        self.tapDown = true
        self.firstPoint = touch.locationInView(self.view)
    }
}

override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
    self.tapDown = false
    self.firstPoint = CGPoint.zero
}

override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
    if let touch = touches.first where self.tapDown {
        let currentPoint = touch.locationInView(self.view)
        let context = UIGraphicsGetCurrentContext()
        CGContextSetStrokeColorWithColor(context, UIColor.redColor().CGColor)
        let lines = [CGPointMake(self.firstPoint.x,self.firstPoint.y),CGPointMake(currentPoint.x,currentPoint.y)]
        CGContextAddLines(context,lines,4)
        CGContextStrokePath(context)
    }
}

In ViewController.swift after viewDidLoad I put this:

UIGraphicsBeginImageContext(skView.frame.size)

Whats wrong here?

Brian
  • 14,610
  • 7
  • 35
  • 43
NovumCoder
  • 4,349
  • 9
  • 43
  • 58

2 Answers2

1

UIGraphicsGetCurrentContext() returns the current CoreGraphics drawing context. There's only a current drawing context in two scenarios:

  • if you're inside a UIView drawRect: method (or code invoked from one, or similar functions such as those for CALayers)
  • if you've started your own CG context and made it "current" by calling UIGraphicsPushContext.

Neither of these is the case in your touchesMoved method, so the call returns nil and the subsequent drawing code fails. (I'd be surprised if it's failing silently... aren't there at least some console messages about drawing with a nil context?)

Moreover, SpriteKit doesn't draw using CoreGraphics — it renders on the GPU using OpenGL or Metal, so you don't issue drawing commands in SpriteKit so much as describe the scene that SpriteKit should draw. See this answer for an example of using SKShapeNode to add a line to a SpriteKit scene.

Community
  • 1
  • 1
rickster
  • 124,678
  • 26
  • 272
  • 326
  • This is exactly the answer I would have written if I had written an answer. – Caleb Jan 14 '16 at 18:42
  • I dont get my nil context because i called UIGraphicsBeginImageContext(skView.frame.size) in viewDidLoad. So there is actually a context available – NovumCoder Jan 14 '16 at 19:22
  • @NovumCoder `UIGraphicsBeginImageContext` is for creating an offscreen image. The drawing you do to the context you create with that function won't appear on the screen. – Caleb Jan 14 '16 at 19:37
0

Ok i got it working, i use SKShapeNode now, but the reason was i was using touch.locationInView instead of touch.locationInNode, which gave other coordinates for my touch point.

What is the difference between locationInView and locationInNode???

Working code:

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    if let touch = touches.first {
        self.tapDown = true
        self.firstPoint = touch.locationInNode(self)
    }
}

override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
    self.tapDown = false
    self.firstPoint = CGPoint.zero
    self.enumerateChildNodesWithName("line", usingBlock: {node, stop in
        node.removeFromParent()
    })
}

override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
    self.enumerateChildNodesWithName("line", usingBlock: {node, stop in
        node.removeFromParent()
    })
    if let touch = touches.first where self.tapDown {
        let currentPoint = touch.locationInNode(self)
        let path = CGPathCreateMutable()
        CGPathMoveToPoint(path, nil, self.firstPoint.x, self.firstPoint.y)
        CGPathAddLineToPoint(path, nil, currentPoint.x, currentPoint.y)


        let shapeNode = SKShapeNode()
        shapeNode.path = path
        shapeNode.name = "line"
        shapeNode.glowWidth = 2.5
        shapeNode.strokeColor = UIColor.blueColor()
        shapeNode.lineWidth = 2
        shapeNode.zPosition = 1

        self.addChild(shapeNode)
    }
}
NovumCoder
  • 4,349
  • 9
  • 43
  • 58