如何使用 CGContext 方法清除旧数据的绘制?

Posted

技术标签:

【中文标题】如何使用 CGContext 方法清除旧数据的绘制?【英文标题】:How can I clear drawing of old data using CGContext methods? 【发布时间】:2014-02-23 19:39:08 【问题描述】:

我有一个 iPad 应用程序,我在其中沿 x 轴绘制日期网格并沿 y 轴向下绘制时间。然后我在这个网格的特定部分绘制彩色条(使用 CGContext 方法)(见图)。

当我尝试重新绘制网格时,旧条仍然存在!我如何清除那里的旧酒吧?我已经尝试了在 Google 和 SO 上可以找到的所有内容,但似乎没有任何效果。

更新1:这里是“驱动代码”...注意没有使用CGRect

CGContextRef currentContext = UIGraphicsGetCurrentContext();  // Get the current graphics context
// Start the line at this point (x,y)
CGContextMoveToPoint(currentContext, column, startPosY);

// compute end point  (additional fDurationSegments takes line width into consideration)
CGContextAddLineToPoint(currentContext, column,  startPosY + (fDurationSegments * FIFTEEN_MINUTE_INCREMENT));

//  draw the colored appointment line
CGContextSetLineDash(currentContext, 0, nil, 0);  //  reset dashed line to straight line
CGContextSetLineWidth(currentContext, LINE_WIDTH);  // Set the width for the lines

CGContextStrokePath(currentContext);  //  draw 'em

更新 2:我将另一个 UIView 放在网格视图的顶部,使其透明并绘制条形...仍然没有用新的东西替换旧的东西。

【问题讨论】:

【参考方案1】:

您应该使用CGContextClearRect 清除以前的绘图,但对于任何认真的答案,请在此处提供您的驾驶代码

【讨论】:

在获得当前上下文后立即使用CGContextClearRect(currentContext, self.bounds),请参阅文档developer.apple.com/library/ios/DOCUMENTATION/GraphicsImaging/…中的详细信息 它将整个区域更改为黑色...似乎没有清除顶部 UIView(我正在绘制约会的那个...也来自文档:但是,则不应在窗口或位图上下文以外的上下文中使用此函数。 你应该在你想要清除的视图上调用clear rect,如果变成黑色是好的意味着清除工作,将背景颜色设置为清除颜色,一切都应该没问题。如果没有,请添加更新的代码。【参考方案2】:

来自 Apple 开发者论坛:

为了让这一切正常工作,viewController 需要参与进来。 viewController 需要一个 IBOutlet 到在情节提要中创建的实际 WeeksAppts 视图。您可以通过控制从情节提要中的视图拖动到 viewController 源代码来创建 IBOutlet。视图控制器中的 IBOutlet 看起来像这样

@property (weak, nonatomic) IBOutlet WeeksAppts *weeksApptsView;

当某些事情发生变化时,视图控制器需要使用这样的一行代码来强制更新视图

[self.weeksApptsView setNeedsDisplay];

【讨论】:

【参考方案3】:

经过多次试验和磨难,我找到了解决您遇到的相同问题的方法。我已经在 *** 上查看了其他类似的问题,但没有解决。所以概念如下:

清晰的 CGContext 流程

    画一个红色三角形 CGContextBeginTransparencyLayer(context,nil) 画一个蓝色圆圈 CGContextClearRect(context,bounds)//现在只会清除在调用 CGContextBeginTransparencyLayer 之后生成的图形 画一个黄色方块 CGContextEndTransparencyLayer(上下文)

结果:您现在将在视图中看到一个红色三角形和一个黄色正方形(蓝色圆圈已被移除)

注意:通过使用 CGContextBeginTransparencyLayer 和 CGContextEndTransparencyLayer,您可以避免在应用程序上下文中创建一个贯穿每个图形的透明孔,如果您在没有上述 TransparencyLayer 过程的情况下使用 CGContextClearRect,就会出现这种情况。

一个有效的 Swift Playground 示例:

import Cocoa
import XCPlayground

class A:Shape
    override func drawRect(dirtyRect: NSRect) 
        super.drawRect(dirtyRect)
        let nsctx:NSGraphicsContext/**/ = NSGraphicsContext.currentContext()!
        let context/**/  = nsctx.CGContext

        let path:CGMutablePathRef  = CGPathCreateMutable();
        let rectangle:CGRect = CGRectMake(0.0, 0.0,200.0, 200.0);
        CGPathAddRect(path,nil, rectangle);
        CGContextAddPath(context,path)
        CGContextSetFillColorWithColor(context,NSColor.greenColor().CGColor)
        CGContextDrawPath(context, CGPathDrawingMode.Fill)

    

class B:Shape
    override func drawRect(dirtyRect: NSRect) 
        super.drawRect(dirtyRect)
        let nsctx:NSGraphicsContext/**/ = NSGraphicsContext.currentContext()!
        let context/**/  = nsctx.CGContext//was graphicsPort

        CGContextBeginTransparencyLayer(context, nil);

        CGContextAddPath(context,CircleParser.circlePath(100,100,100))
        CGContextSetFillColorWithColor(context,NSColor.purpleColor().CGColor)
        CGContextDrawPath(context, CGPathDrawingMode.Fill)

        CGContextClearRect(context, NSMakeRect(0, 0, dirtyRect.width, dirtyRect.height))

        CGContextAddPath(context,CircleParser.circlePath(60,60,50))
        CGContextSetFillColorWithColor(context,NSColor.blueColor().CGColor)
        CGContextDrawPath(context, CGPathDrawingMode.Fill)

        CGContextEndTransparencyLayer(context);
    


class Shape:FlippedView
    init() 
        let frame = NSRect(x: 0, y: 0, width: 300, height: 300)
        super.init(frame: frame)
    
    /*
     * Required by super class
     */
    required init?(coder: NSCoder) 
        fatalError("init(coder:) has not been implemented")
    


class Container:FlippedView
    init() 
        let frame = NSRect(x: 0, y: 0, width: 500, height: 500)
        super.init(frame: frame)
        //self.wantsLayer = true
    
    /*
     * Required by super class
     */
    required init?(coder: NSCoder) 
        fatalError("init(coder:) has not been implemented")
    

class FlippedView:NSView //Organizes your view from top to bottom
    override var flipped:Bool 
        get 
            return true
        
    


let container = Container()
let a = A()
let b = B()
container.addSubview(a)
container.addSubview(b)

XCPlaygroundPage.currentPage.liveView = container

【讨论】:

【参考方案4】:
[self setBackgroundColor:[UIColor clearColor]];

它清除所有以前的绘图并为新绘图提供一个干净的状态。

【讨论】:

以上是关于如何使用 CGContext 方法清除旧数据的绘制?的主要内容,如果未能解决你的问题,请参考以下文章

使用 CGContext 绘制后擦除

如何检查 CGContext 是不是包含点?

重复使用时如何完全清除单元格?

在 iOS7 中使用 CGContext 绘制问题

如何使用函数调用正确更新 CGContext?

为 PaintCode CGContext 自动调整标签中的文本