【问题标题】:Why does my drawing lag after drawing for a long period of time?为什么我画了很长一段时间后画图会卡顿?
【发布时间】:2016-05-29 20:08:18
【问题描述】:

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

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 上测试的示例: 左边是画了一堆循环后的锯齿状数字。右边是我画的前几个数字,很流畅。

【问题讨论】:

    标签: ios drawrect cgcontext cgpoint


    【解决方案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:

    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 返回的矩形就会考虑在内。

    【讨论】:

    • 这行得通!唯一的问题发生在我绘制一段时间并且开始绘制新形状时,它会滞后一秒钟(仅当我从几个点开始时)。你知道这可能是什么吗?
    • 更新:我解决了这个问题。我所做的只是将 self.setNeedsDisplayInRect 复制并粘贴到我的 touchesBegan 中,并将前两个参数的参数替换为 lastPoint。非常感谢!
    猜你喜欢
    • 2018-08-13
    • 2021-04-05
    • 2015-09-27
    • 2018-02-18
    • 1970-01-01
    • 2018-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多