【问题标题】:Don't clear the context before drawing绘制前不要清除上下文
【发布时间】:2012-12-11 21:16:20
【问题描述】:

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

这是我的绘图方法:

-(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 时,视图被完全清除了。 有没有办法让我的方法起作用?

【问题讨论】:

    标签: objective-c ios drawing graphicscontext


    【解决方案1】:

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

    - (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)”循环中调用以在继续之前绘制待处理的服务器源图形(请参阅源代码中添加的注释)。

    【讨论】:

    • 我在哪里可以调用你的 drawRect 中的 drawInContext() 方法?
    • @Seb 这个想法是你有一组手势和其他用户操作,当它们发生时会在离线上下文上绘制。此外,这些操作会调用 setNeedsDisplay: true,因此 UIView 会自行重绘。当它重绘时,它会自行清除,但随后会复制包含所有图形历史记录的图层。
    • 我想我理解了这个选择的原因,但我不确定如何在我的应用程序中使用它。我有服务器发送给我的线条,我想在第一次启动时将它们绘制在视图上。在那之后,我想画新线而不重画一切。实际上,使用您的方法(我没有更改任何内容),我的绘图都不会显示,并且在我创建一个新绘图后线条会被删除。我清楚了吗?你能更准确地解释我吗?对不起,我是初学者...:/
    • offlineContext_1的图形如何显示在绘图视图上?
    • @Seb 调用 CGContextDrawLayerAtPoint() 是绘制离线上下文的地方。离线上下文(我的术语)和层(来自对 CGLayerCreateWithContext() 的调用)之间存在潜在的关系。您可以根据需要在该上下文上绘制所有内容,然后使用 CGContextDrawLayerAtPoint() 调用将图层绘制到实际上下文中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多