【问题标题】:CoreGraphics in iOS: how can I save the paths drawn in a CGContext and retrieve them in the next draw call?iOS 中的 CoreGraphics:如何保存在 CGContext 中绘制的路径并在下一次绘制调用中检索它们?
【发布时间】:2016-01-18 15:47:35
【问题描述】:

编辑:

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


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

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


我得到了什么:

这是我在 first 绘制调用中得到的:

这是我在 第二次 通话后得到的:

这是我在第二次通话后想要得到的


代码如下:

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)

    }
}

【问题讨论】:

    标签: ios swift core-animation cgcontext cgcontextdrawpath


    【解决方案1】:

    每次调用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 方法中将它blit到屏幕上。

    【讨论】:

    • 好的。我想要实现的是在第二次调用 drawRect 时跳过对 firstDraw() 的调用。原因是在我的真实代码中我有很多数据点和线要绘制,所以我认为如果我回收以前绘制的东西我可以优化性能。使用 CoreGraphics 是否有可能?
    【解决方案2】:

    使用UIGraphicsPushContext(context) 而不是CGContextSaveGState(context) 使您的上下文成为当前绘图上下文。

    此处描述的差异:CGContextSaveGState vs UIGraphicsPushContext

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多