I have an iPad app where I draw a grid of dates along the x axis and times down the y axis. I then draw colored bars (using CGContext methods) in specific sections of this grid (see image). enter image description here

When I try to re-draw the grid, the old bars are still there! How do I clear the old bars out of there? I've tried everything I could find on Google and SO, but nothing seems to work.

UPDATE 1: here is the "driving code"... note that there is no use of 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

UPDATE 2: I put another UIView on top of the grid's view, made it transparent and drew the bars... still didn't replace the old stuff with the new.

有帮助吗?

解决方案 2

From the Apple Developer's Forum:

In order to get this all to work, the viewController needs to be involved. The viewController needs an IBOutlet to the actual WeeksAppts view that was created in the storyboard. You can create the IBOutlet by control-dragging from the view in storyboard to the viewController source code. The IBOutlet in the view controller will look something like this

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

When something changes, the view controller needs to force an update to the view with a line of code like this

[self.weeksApptsView setNeedsDisplay];

其他提示

You should use CGContextClearRect to clear previous drawing, but for any kind serious answer please provide your driwing code here

After much trials and tribulations ive found a solution to the same problem you had. Ive looked at other similar problems here on StackOverflow but non has paned out. So the concept is as follows:

A clear procedure for CGContext

  1. Draw a red triangle
  2. CGContextBeginTransparencyLayer(context,nil)
  3. Draw a blue circle
  4. CGContextClearRect(context,bounds)//will now only clear graphics made after the CGContextBeginTransparencyLayer call was made
  5. Draw a yellow square
  6. CGContextEndTransparencyLayer(context)

Result: You will now have a red triangle and a yellow square in the view (the blue circle was removed)

NOTE: by using CGContextBeginTransparencyLayer and CGContextEndTransparencyLayer you avoid making a transparent hole that would extend through every graphic in the application context, which would be the case if you used CGContextClearRect without the TransparencyLayer procedure described above.

A working Swift Playground example:

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
[self setBackgroundColor:[UIColor clearColor]];

It clears all the previous drawing and gives a clean slate for new drawing.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top