绘制曲线没有滞后? [英] Drawing curved lines without lagging?

查看:35
本文介绍了绘制曲线没有滞后?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a class below that when attached to a view draws curved lines when the user touches their device. The problem is that the lines drawn seem to lag behind from the position of the finger on the screen. The lagging is enough to be noticeable and mildly annoying as new sections of the line display a small distance away from the finger touching the screen.

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

The code uses the addCurveToPoint curve method. (The alternative addQuadCurveToPoint curve method appears to be less superior in terms of a quality curved line but does display on screen faster.)

我怀疑这个问题与在 counter == 4 后调用 setNeedsDisplay 时有关.在绘制曲线之前,代码会等待,直到在绘制时接收到 4 个新的触摸点.理想情况下,在每个触摸点(即 counter == 1)绘制一条曲线,消除滞后.(更改 Counter == 1 似乎不起作用.)

I suspect that this issue relates to when setNeedsDisplay is called once the counter == 4. It appears the code waits until 4 new touch points are received while drawing before a curved line is drawn. Ideally a curved line is drawn at every single touch point (i.e. counter == 1), eliminating the lagging. (Changing Counter == 1 doesn't seem to work.)

我迷路了,不知道如何更新代码以进一步改进它以消除短暂的滞后但保留曲线.需要在下面的代码中进行哪些更改以消除短暂的延迟?

I'm lost and don't know how to update the code to improve it further to remove that short lag but retain the curved lines. What needs to change in the below code to remove that short lag?

// 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()
}
}

推荐答案

首先,我相信你做错了.如果您想绘制几条线,而不是由用户输入,而是绘制圆形、波浪线、简单的东西,这通常很有效.

To start, I believe that you are doing it wrong. This usally works well if you want to draw a few lines not nesscarly by the users input but for circles, squiggly lines, simple things.

使用时:

self.setNeedsDisplay()

您每次都在重绘所有线条!这是坚固的 CPU,这就是为什么你有滞后.图像用户绘制几百条线,然后绘制成一千条线,每次他/她触摸屏幕时,它都会重新绘制所有这些线.

You are redrawing ALL the lines EVERYTIME! this is tough CPU and that's why you have a lag. Image the user draws a few hundred lines then into a thousand and everytime he/she touches the screen it will redraw ALL of those lines.

好的.所以,我建议做的是有 2 个 UIImageViews: 1) mainImageView - 它将保存整体绘图.2) tempImageView - 用户将使用它来绘制.

OK. So, What I recommend doing is have 2 UIImageViews: 1) mainImageView - which will hold the overall drawing. 2) tempImageView - which the user will use to draw.

当用户在tempImageView"上触摸/绘制时,它会一直绘制直到松开屏幕,然后将tempImageView"合并到mainImageView"

When the user touches/draws on "tempImageView" it draws until they let go of the screen then merge "tempImageView" to "mainImageView"

这里有一个教程:

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

这篇关于绘制曲线没有滞后?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆