Draw a Straight Line in Swift 3 and Core Graphics

draw a straight line in swift 3 and core graphics

You need keep the current context until the line draw process has ended, after that you need keep the current image and clear the context, draw the saved image again, and draw the new line. When the touch ended is called clean the current context and save the current image, after that start the new line draw process again

this is the full code

import UIKit

class ViewController2: UIViewController {

@IBOutlet weak var drawingPlace: UIImageView!

var startTouch : CGPoint?
var secondTouch : CGPoint?
var currentContext : CGContext?
var prevImage : UIImage?

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first
startTouch = touch?.location(in: drawingPlace)
}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in touches{
secondTouch = touch.location(in: drawingPlace)

if(self.currentContext == nil)
{
UIGraphicsBeginImageContext(drawingPlace.frame.size)
self.currentContext = UIGraphicsGetCurrentContext()
}else{
self.currentContext?.clear(CGRect(x: 0, y: 0, width: drawingPlace.frame.width, height: drawingPlace.frame.height))
}

self.prevImage?.draw(in: self.drawingPlace.bounds)

let bezier = UIBezierPath()

bezier.move(to: startTouch!)
bezier.addLine(to: secondTouch!)
bezier.close()

UIColor.blue.set()

self.currentContext?.setLineWidth(4)
self.currentContext?.addPath(bezier.cgPath)
self.currentContext?.strokePath()
let img2 = self.currentContext?.makeImage()
drawingPlace.image = UIImage.init(cgImage: img2!)
}
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {

self.currentContext = nil
self.prevImage = self.drawingPlace.image
}
}

results

Sample Image

How to draw a line in Swift 3

To draw a line between two points the first thing you need is get the CGPoints from the current UIView, there are several ways of achieve this. I going to use an UITapGestureRecognizer for the sake of the sample to detect when you make a tap.

The another step is once you have the two points saved draw the line between the two points, and for this again you can use the graphics context as you try before or use CAShapeLayer.

So translating the explained above we get the following code:

class ViewController: UIViewController {

var tapGestureRecognizer: UITapGestureRecognizer!

var firstPoint: CGPoint?
var secondPoint: CGPoint?

override func viewDidLoad() {
super.viewDidLoad()

tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.showMoreActions(touch:)))
tapGestureRecognizer.numberOfTapsRequired = 1
view.addGestureRecognizer(tapGestureRecognizer)
}

func showMoreActions(touch: UITapGestureRecognizer) {
let touchPoint = touch.location(in: self.view)

guard let _ = firstPoint else {
firstPoint = touchPoint
return
}

guard let _ = secondPoint else {
secondPoint = touchPoint
addLine(fromPoint: firstPoint!, toPoint: secondPoint!)

firstPoint = nil
secondPoint = nil

return
}
}

func addLine(fromPoint start: CGPoint, toPoint end:CGPoint) {
let line = CAShapeLayer()
let linePath = UIBezierPath()
linePath.move(to: start)
linePath.addLine(to: end)
line.path = linePath.cgPath
line.strokeColor = UIColor.red.cgColor
line.lineWidth = 1
line.lineJoin = kCALineJoinRound
self.view.layer.addSublayer(line)
}
}

The above code is going to draw a line every time two points are selected and you can customize the above function as you like.

I hope this help you.

Drawing lines with core graphics

Try drawing the line using CAShapeLayer like so:

func addLine(fromPoint start: CGPoint, toPoint end:CGPoint) {
let line = CAShapeLayer()
let linePath = UIBezierPath()
linePath.move(to: start)
linePath.addLine(to: end)
line.path = linePath.cgPath
line.strokeColor = UIColor.red.cgColor
line.lineWidth = 1
line.lineJoin = kCALineJoinRound
self.view.layer.addSublayer(line)
}

Hope this helps!

How to draw a line in the simplest way in swift

Try looking into UIBezierPath, it will help you a lot for drawing lines. Here is documentation. Here is an example:

override func drawRect(rect: CGRect) {
let aPath = UIBezierPath()

aPath.move(to: CGPoint(x:<#start x#>, y:<#start y#>))
aPath.addLine(to: CGPoint(x: <#end x#>, y: <#end y#>))

// Keep using the method addLine until you get to the one where about to close the path
aPath.close()

// If you want to stroke it with a red color
UIColor.red.set()
aPath.lineWidth = <#line width#>
aPath.stroke()
}

Make sure you put this code in the drawRect, like in the example above.

If you need to update the drawing just call setNeedsDisplay() to update.

Draw a line realtime with Swift 3.0

You have to begin the image context:

UIGraphicsBeginImageContextWithOptions(view.bounds.size, false, 0)

You also have to stroke the path:

context?.strokePath()

You also are not drawing the previous image:

imageView.image?.draw(in: view.bounds)

Thus:

func drawLine(from fromPoint: CGPoint, to toPoint: CGPoint) {
UIGraphicsBeginImageContextWithOptions(view.bounds.size, false, 0)

imageView.image?.draw(in: view.bounds)

let context = UIGraphicsGetCurrentContext()

context?.move(to: fromPoint)
context?.addLine(to: toPoint)

context?.setLineCap(CGLineCap.round)
context?.setLineWidth(brushWidth)
context?.setStrokeColor(red: red, green: green, blue: blue, alpha: 1.0)
context?.setBlendMode(CGBlendMode.normal)
context?.strokePath()

imageView.image = UIGraphicsGetImageFromCurrentImageContext()
imageView.alpha = opacity
UIGraphicsEndImageContext()
}

Draw straight line swift 4

As Reinier Melian explained drawing straight line using core graphics. When the touch ended draw the save image using CGContext to show in UIImageView.

You need keep the current context until the line draw process has ended, after that you need keep the current image and clear the context, draw the saved image again, and draw the new line. When the touch ended is called clean the current context and save the current image, after that start the new line draw process again.

import UIKit

class ViewController2: UIViewController {

@IBOutlet weak var drawingPlace: UIImageView!

var startTouch : CGPoint?
var secondTouch : CGPoint?
var currentContext : CGContext?
var prevImage : UIImage?

override func viewDidLoad() {
super.viewDidLoad()
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first
startTouch = touch?.location(in: drawingPlace)
}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {

for touch in touches{
secondTouch = touch.location(in: drawingPlace)

if(self.currentContext == nil){
UIGraphicsBeginImageContext(drawingPlace.frame.size)
self.currentContext = UIGraphicsGetCurrentContext()
}else{
self.currentContext?.clear(CGRect(x: 0, y: 0, width: drawingPlace.frame.width, height: drawingPlace.frame.height))
}

self.prevImage?.draw(in: self.drawingPlace.bounds)

let bezier = UIBezierPath()

bezier.move(to: startTouch!)
bezier.addLine(to: secondTouch!)
bezier.close()

UIColor.blue.set()

self.currentContext?.setLineWidth(4)
self.currentContext?.addPath(bezier.cgPath)
self.currentContext?.strokePath()
let img2 = self.currentContext?.makeImage()
drawingPlace.image = UIImage.init(cgImage: img2!)

}
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {

self.currentContext = nil
self.prevImage = self.drawingPlace.image
}

}

Drawing simple lines on iPhone with CoreGraphics

The complete code is as below.

/* Set the color that we want to use to draw the line */ 
[[UIColor brownColor] set];
/* Get the current graphics context */
CGContextRef currentContext =UIGraphicsGetCurrentContext();
/* Set the width for the line */
CGContextSetLineWidth(currentContext,5.0f);
/* Start the line at this point */
CGContextMoveToPoint(currentContext,50.0f, 10.0f);
/* And end it at this point */
CGContextAddLineToPoint(currentContext,100.0f, 200.0f);
/* Use the context's current color to draw the line */
CGContextStrokePath(currentContext);

swift and sprite kit drawing a straight line while dragging your finger on the screen

SpriteKit has some of the worst 2D drawing ever presented in a 2D game engine.

Actually, the worst.

SKShapeNode and its CGPath are atrocious nonsense. It's as if the
"designers" of SpriteKit have never once looked at the most primitive
of 2D drawing in anything like DirectX or OpenGL. Let alone the kinds
of things that animators might want to do with lines and shape
creation, mutation, distortion and progress and line animation. ~ Confused


Having gotten that little rant off my chest, in the vain hope that it recalibrates your expectations to not expect a drawing style solution, consider this:

SKSpriteNodes can be a simple box, and they can be scaled in both the X and Y axis, and they can be parented to a "dummy" SKNode that rotates to face the direction of the current touch, relative to the original position of the touch.

SO.... you can draw a skinny box, starting at the point of the initial touch, and as the touch is moved, scale the SKSpriteNode to that point by both rotating the SKDummyNode you create to be the parent of your "line", and then scaling it out along that length from the origin to the current position of the touch.

Viola, a LINE!

Of sorts.

Why drawing straight lines using Core Graphics I get dashed lines?

I believe you are seeing the result of the button's title text drawing over the image. Check out the following demo using your code in a Playground:

Sample Image

Core Graphics Graph lines not drawing

I tested your code in swift 4. The axis lines are not shown. An alternative, you can use "addLines" function like below.

xAxisPath.addLines(between: [CGPoint(x: padding, y: rect.size.height - 31), CGPoint(x: axisWidth, y: rect.size.height - 31)])


Related Topics



Leave a reply



Submit