为什么我的绘图在画了很长一段时间后会滞后?

时间:2016-05-29 20:08:18

标签: ios drawrect cgcontext cgpoint

我正在创建一个绘图应用。一开始我的绘画很流畅。当我画了很长一段时间的圆圈时,我的绘画开始变得前卫。也许事实是阵列无法处理太多的点?

DV.swift:

   override func touchesBegan(touches: Set<UITouch>, withEvent       event: UIEvent?) {
    lastPoint = touches.first!.locationInView(self)

    self.setNeedsDisplay()
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
    var newPoint = touches.first!.locationInView(self)

    lines.append(Line(start: lastPoint, end: newPoint))

    lastPoint = newPoint

    self.setNeedsDisplay()

}

override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
    var veryFirstPoint = touches.first!.locationInView(self)
    lines.append(Line(start: lastPoint, end:veryFirstPoint))
    self.setNeedsDisplay()
}


override func drawRect(rect: CGRect) {
    var context = UIGraphicsGetCurrentContext()
    CGContextBeginPath(context)

    for line in lines {

        CGContextMoveToPoint(context,line.start.x , line.start.y)
        CGContextAddLineToPoint(context, line.end.x, line.end.y)


    }
    CGContextSetRGBFillColor(context, 0, 0, 0, 1)

    CGContextSetLineWidth(context, 5)
    CGContextStrokePath(context)
    }

在iPad mini 4上测试的示例: 在绘制一堆循环后,左侧是锯齿状的数字。右边是我画的前几个数字,他们很顺利。

enter image description here

1 个答案:

答案 0 :(得分:1)

你是对的。每次添加新的“行”时,都会让CPU重绘许多路径,即每次触摸后。您拥有的线路越多,处理器越来越密集。一种解决方案是仅重绘视图的“脏”部分。您可以使用setNeedsDisplayInRect(rect:CGRect)代替setNeedsDisplay()来执行此操作。例如,您可以添加扩展名:

extension CGRect{
    static func rectWithTwoPoints(p1:CGPoint,p2:CGPoint) -> CGRect
    {
        return CGRectMake(min(p1.x, p2.x),min(p1.y, p2.y),fabs(p1.x - p2.x),fabs(p1.y - p2.y));
    }
}

这将给我一个包含任意两点的矩形。现在,在touchesMoved:touchesEnded:,我们可以像setNeedsDisplayInRect:那样致电:{/ p>

override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
        let newPoint = touches.first!.locationInView(self)

        lines.append(Line(start: lastPoint, end: newPoint))

        lastPoint = newPoint

        self.setNeedsDisplayInRect(CGRectInset(CGRect.rectWithTwoPoints((lines.last?.start)!, p2: (lines.last?.end)!),-10.0,-10.0)) //would be better to not force unwrap and use magic numbers, but you get the idea
    }

    override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
        let veryFirstPoint = touches.first!.locationInView(self)
        lines.append(Line(start: lastPoint, end:veryFirstPoint))
        self.setNeedsDisplayInRect(CGRectInset(CGRect.rectWithTwoPoints((lines.last?.start)!, p2: (lines.last?.end)!),-10.0,-10.0))
    }

使用CGRectInset扩展我们的矩形,因为我们有一个路径宽度,如果我们只重绘rectWithTwoPoints返回的rect,则会考虑到这一点。