绘制曲线没有滞后?

时间:2015-11-04 16:44:57

标签: ios swift uiview uikit uibezierpath

我在下面有一个类,当附加到视图时,当用户触摸他们的设备时绘制曲线。问题是绘制的线条似乎落后于手指在屏幕上的位置。由于线条的新部分距离触摸屏幕的手指有一小段距离,因此滞后足以引人注意并且有点烦人。

代码使用addCurveToPoint曲线方法。 (替代addQuadCurveToPoint曲线方法在质量曲线方面似乎不那么优越,但在屏幕上显示得更快。)

我怀疑此问题与setNeedsDisplay时调用counter == 4的时间有关。看起来代码等待直到绘制曲线之前绘制时接收到4个新触摸点。理想地,在每个单个触摸点(即,计数器== 1)绘制曲线,消除滞后。 (更改Counter == 1似乎不起作用。)

我迷路了,不知道如何更新代码以进一步改进它以消除短暂的延迟,但保留曲线。 以下代码需要更改哪些内容才能消除这种短暂的延迟?

// 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 个答案:

答案 0 :(得分:0)

首先,我相信你做错了。如果你想通过用户输入画出几条线而不是用于圈子,波浪线,简单的东西,这通常很有用。

使用时:

self.setNeedsDisplay()

您每隔一段时间重绘所有行!这是一个艰难的CPU,这就是为什么你有一个滞后。图像用户绘制几百行然后变成一千行,每当他/她触摸屏幕时,它将重绘所有这些行。

行。所以,我建议做的是有2个UIImageViews:1)mainImageView - 它将保存整个绘图。 2)tempImageView - 用户将用于绘制。

当用户触摸/绘制“tempImageView”时,它会绘制直到他们放开屏幕,然后将“tempImageView”合并到“mainImageView”

这是一个关于以下内容的教程:

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