iOS中的CoreGraphics:如何保存CGContext中绘制的路径并在下次绘制调用中检索它们?

时间:2016-01-18 15:47:36

标签: ios swift core-animation cgcontext cgcontextdrawpath

编辑:

我想要实现的是第二次调用drawRect时跳过对firstDraw()的调用。原因是在我的真实代码中我有很多数据点和线条要绘制,所以我想如果我回收以前绘制的东西,我可以优化性能。这对CoreGraphics来说是否可行?

我希望能够在UIView上执行多个绘图,而无需重新绘制我已绘制的内容。

以下代码将以2.4秒的时间距离执行两次绘制。第一次调用后,我使用 CGContextSaveGState 来保存状态。在第二个调用中,我检索当前的图形上下文,然后添加一些行。然而,这似乎失败了,因为它似乎丢失了先前的上下文。

我得到了什么:

以下是我在第一次绘制调用中获得的内容:

enter image description here

以下是第二次电话后的结果:

enter image description here

在第二次调用之后,这是我想要获得的内容:

enter image description here

以下是代码:

import UIKit

class GraphView: UIView {

    var count : Int = 0

    override func drawRect(rect: CGRect) {
        if ( count == 0){
            firstDraw()
         NSTimer.scheduledTimerWithTimeInterval(2.4, target: self, selector: "setNeedsDisplay", userInfo: nil, repeats: false)
            count++
        }
        else{
            addLinesToDraw()
        }
    }

    func firstDraw(){
        // Drawing code
        let context = UIGraphicsGetCurrentContext()

        CGContextMoveToPoint(context, 50, 50);

        CGContextSetRGBStrokeColor(context, 0, 0, 0, 1.0);
        CGContextSetRGBFillColor(context, 0, 0.0, 0.0, 1.0);
        CGContextAddLineToPoint(context, 60, 60);
        CGContextMoveToPoint(context, 150, 150);
        CGContextAddLineToPoint(context, 110, 90);
        CGContextSetLineWidth(context, 2);
        CGContextStrokePath(context);

        // Draw a Point as a small square
        CGContextSetRGBStrokeColor(context, 0.5, 0.5, 0.5, 1.0);
        CGContextSetRGBFillColor(context, 0.5, 0.5, 0.5, 1.0);
        //NSLog(@"Drawing rect at point [x: %i, y: %i]", xPosition+resolution, pressureIntValue);
        CGContextFillRect(context, CGRectMake(0, 0, 10, 10));
        CGContextAddRect(context, CGRectMake(0, 0, 10, 10));
        CGContextStrokePath(context);

        CGContextSaveGState(context)
    }

    func addLinesToDraw(){
        // Drawing code
        let context = UIGraphicsGetCurrentContext()

        CGContextMoveToPoint(context, 30, 60);

        CGContextSetRGBStrokeColor(context, 0, 0, 0, 1.0);
        CGContextSetRGBFillColor(context, 0, 0.0, 0.0, 1.0);
        CGContextAddLineToPoint(context, 20, 20);
        CGContextMoveToPoint(context, 120, 250);
        CGContextAddLineToPoint(context, 110, 90);
        CGContextSetLineWidth(context, 2);
        CGContextStrokePath(context);

        // Draw a Point as a small square
        CGContextSetRGBStrokeColor(context, 0.5, 0.5, 0.5, 1.0);
        CGContextSetRGBFillColor(context, 0.5, 0.5, 0.5, 1.0);
        //NSLog(@"Drawing rect at point [x: %i, y: %i]", xPosition+resolution, pressureIntValue);
        CGContextFillRect(context, CGRectMake(20, 30, 10, 10));
        CGContextAddRect(context, CGRectMake(20, 30, 10, 10));
        CGContextStrokePath(context);

        CGContextSaveGState(context)

    }
}

2 个答案:

答案 0 :(得分:0)

每次拨打drawRect:时,都必须从头开始绘制所有内容。因此,在您的情况下,您希望将代码更改为:

override func drawRect(rect: CGRect) {
    firstDraw()

    if ( count == 0){
     NSTimer.scheduledTimerWithTimeInterval(2.4, target: self, selector: "setNeedsDisplay", userInfo: nil, repeats: false)
        count++
    }
    else{
        addLinesToDraw()
    }
}

如果您不喜欢这个解决方案,您可以随时在单独的CGContext中完成所有绘图,并使用drawRect方法将其显示在屏幕上。

答案 1 :(得分:0)

使用UIGraphicsPushContext(context)代替CGContextSaveGState(context)使您的上下文成为当前绘图环境。

这里描述的差异:CGContextSaveGState vs UIGraphicsPushContext