draw a straight line in swift 3 and core graphics

2019-05-10 12:13发布

问题:

I'm trying to draw a single, straight line using core graphics and swift 3 However, when touchesmoved is called, it creates multiple lines instead of just a single line. Code used is below:

import UIKit

    class ViewController: UIViewController {

        @IBOutlet weak var drawingPlace: UIImageView!

        var startTouch : CGPoint?
        var secondTouch : CGPoint?

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

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

                UIGraphicsBeginImageContext(drawingPlace.frame.size)
                drawingPlace.image?.draw(in: CGRect(x: 0, y: 0, width: drawingPlace.frame.width, height: drawingPlace.frame.height))
                let bezier = UIBezierPath()

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

                bezier.lineWidth = 4
                UIColor.blue.set()
                bezier.stroke()

                let img = UIGraphicsGetImageFromCurrentImageContext()
                UIGraphicsEndImageContext()
                drawingPlace.image = img   
            }
        }
    }

btw touchesEnd creates a single line but only after the user ends the touch. I want the user to see the line being drawn as they touch. thank you.

回答1:

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