Reputation: 4974
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).
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.
Upvotes: 0
Views: 9331
Reputation: 5569
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:
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
Upvotes: 1
Reputation: 4974
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];
Upvotes: 1
Reputation: 5684
You should use CGContextClearRect
to clear previous drawing, but for any kind serious answer please provide your driwing code here
Upvotes: 1
Reputation: 4792
[self setBackgroundColor:[UIColor clearColor]];
It clears all the previous drawing and gives a clean slate for new drawing.
Upvotes: -1