3

我试图找到一种在视图上绘制线条而不重绘所有上下文的方法。

这是我的绘图方法:

-(void)drawInContext:(CGContextRef)context {
    for (int i = 0; i < self.drawings.count; ++i) {
        Drawing* drawing = [self.drawings objectAtIndex:i];

        CGContextSetStrokeColorWithColor(context, drawing.colorTrait.CGColor);
        CGContextSetLineWidth(context, 1.0);

        CGContextMoveToPoint(context, [[drawing.points objectAtIndex:0] CGPointValue].x * self.zoomScale, [[drawing.points objectAtIndex:] CGPointValue].y * self.zoomScale);

        for (int i = 1; i < drawing.points.count; i++) {
            CGContextAddLineToPoint(context, [[drawing.points objectAtIndex:i] CGPointValue].x * self.zoomScale, [[drawing.points objectAtIndex:i] CGPointValue].y * self.zoomScale);
        }

        CGContextStrokePath(context);
    }
}

-(void)drawRect:(CGRect)rect {
    if (isRedrawing) {
        [self drawInContext:UIGraphicsGetCurrentContext()];
        isRedrawing = NO;
    }

    [[UIColor redColor] set];
    [currentPath stroke];
}

但是当我在我的 touches 方法中调用 setNeedsDisplay 时,视图被完全清除了。有没有办法让我的方法奏效?

4

1 回答 1

3

无论好坏,我都使用图层:

- (void)drawRect:(CGRect)rect {

    CGContextRef context = UIGraphicsGetCurrentContext();

    if (first) {

        // Wait for the first call to get a valid context

        first = NO;

        // Then create a CGContextRef (offlineContext_1) and matching CGLayer (layer_1)

        layer_1 = CGLayerCreateWithContext (context,self.bounds.size, NULL);    
        offlineContext_1 = CGLayerGetContext (layer_1);

        // If you have any pending graphics to draw, draw them now on offlineContext_1

    }

    // Normally graphics calls are made here, but the use of an "offline" context means the graphics calls can be made any time.

    CGContextSaveGState(context);

    // Write whatever is in offlineContext_1 to the UIView's context 

    CGContextDrawLayerAtPoint (context, CGPointZero, layer_1);
    CGContextRestoreGState(context);

}

这个想法是,虽然 UIView 的上下文总是被清除,但与 Layer 关联的离线上下文却没有。您可以继续累积图形操作,而不会被 drawRect 清除。

编辑:所以你已经指出了你的问题和我解决的问题之间的一个区别。在第一次显示之前我不需要绘制任何东西,而您想在第一次显示之前绘制一些东西。据我所知,您可以随时以任何大小和分辨率创建图层。我发现最简单的方法是等待将有效上下文(具有当前设备的正确设置)传递给我,然后根据该上下文创建一个新的上下文/层。查看“if (first)”块的内部。

您可以做同样的事情,但您还必须缓存从服务器获取的行等,直到第一个 drawRect: 被调用。然后,您可以使用给定的上下文创建离线上下文,将您从服务器获得的线等绘制到离线上下文,然后绘制图层,如下所示。因此,您要添加到该方法的唯一内容是在“if (first)”循环中调用以在继续之前绘制待处理的服务器源图形(请参阅源代码中添加的注释)。

于 2012-12-11T23:08:09.793 回答