Drawing curve lines without lag?

I have a class below that, when connected to a view, draws curved lines when the user touches his device. The problem is that the lines, which, apparently, lag behind the position of the finger on the screen. The lag is enough to be noticeable and slightly annoying, because new sections of the line are displayed at a short distance from the finger touching the screen.

The code uses the curve method addCurveToPoint. (An alternative curve method addQuadCurveToPointseems to be less effective in terms of a quality curved line, but displays faster on the screen.)

I suspect this problem is due to when setNeedsDisplaycalled after counter == 4. It looks like the code is waiting until 4 new touch points are received when drawing before the curve is drawn. In the ideal case, a curved line is drawn at each point with one touch (i.e. Counter == 1), eliminating the lag. (The change Counter == 1does not seem to work.)

I got lost and don’t know how to update the code to improve it, to remove this short lag, but keep the curved lines. What needs to be changed in the code below to remove this short delay?

// Swift 2 code below tested using Xcode 7.0.1.

class drawView: UIView {

var path:UIBezierPath?
var incrementalImage:UIImage?

var points = [CGPoint?](count: 5, repeatedValue: nil)
var counter:Int?

var infoView:UIView = UIView()
var strokeColor:UIColor?


required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    self.multipleTouchEnabled = false
    self.backgroundColor = UIColor.whiteColor()
    path = UIBezierPath()
    path?.lineWidth = 20.0
    strokeColor = UIColor.darkGrayColor()
    path?.lineCapStyle = CGLineCap.Round
}

override init(frame: CGRect) {
    super.init(frame: frame)
    self.multipleTouchEnabled = false
    path = UIBezierPath()
    path?.lineWidth = 20.0
}


override func drawRect(rect: CGRect) {
    incrementalImage?.drawInRect(rect)
    strokeColor?.setStroke()
    path?.stroke()
}

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    counter = 0
    let touch: AnyObject? = touches.first
    points[0] = touch!.locationInView(self)
    infoView.removeFromSuperview()
}

override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
    let touch: AnyObject? = touches.first
    let point = touch!.locationInView(self)
    counter = counter! + 1
    points[counter!] = point

    if counter == 4{

        points[3]! = CGPointMake((points[2]!.x + points[4]!.x)/2.0, (points[2]!.y + points[4]!.y)/2.0)
        path?.moveToPoint(points[0]!)
        path?.addCurveToPoint(points[3]!, controlPoint1: points[1]!, controlPoint2: points[2]!)

        self.setNeedsDisplay()

        points[0]! = points[3]!
        points[1]! = points[4]!
        counter = 1

    }
}

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

    self.drawBitmap()
    self.setNeedsDisplay()
    path?.removeAllPoints()
    counter = 0
}

override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) {
    self.touchesEnded(touches!, withEvent: event)
}

func drawBitmap(){
        UIGraphicsBeginImageContextWithOptions(self.bounds.size, true, 0.0)
        strokeColor?.setStroke()
        if((incrementalImage) == nil){
            let rectPath:UIBezierPath = UIBezierPath(rect: self.bounds)
            UIColor.whiteColor().setFill()
            rectPath.fill()
        }

        incrementalImage?.drawAtPoint(CGPointZero)
        path?.stroke()
        incrementalImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
}
}
+1
source share
1 answer

, , . , nesscarly , , squiggly , .

:

self.setNeedsDisplay()

! , . , , , , .

OK. , , 2 UIImageViews: 1) mainImageView - . 2) tempImageView - .

/ "tempImageView", , , "tempImageView" "mainImageView"

:

http://www.raywenderlich.com/87899/make-simple-drawing-app-uikit-swift

0

Source: https://habr.com/ru/post/1614567/


All Articles