I have a Mac app that's using IKImageBrowserView. I've subclassed IKImageBrowserView and I'm returning a custom cell type from newCellForRepresentedItem.
In my cell, I'm creating and returning a layer from layerForType:
// When asked for a foreground layer, return a new layer that we'll render the icon decorations into
- (CALayer *)layerForType:(NSString *)type {
if ([type isEqualToString:IKImageBrowserCellForegroundLayer]) {
@synchronized(self) {
if (!self.foregroundLayer) {
self.foregroundLayer = [[CALayer alloc] init];
self.foregroundLayer.delegate = self;
self.foregroundLayer.needsDisplayOnBoundsChange = YES;
[self.foregroundLayer setNeedsDisplay];
}
}
return self.foregroundLayer;
} else {
return [super layerForType:type];
}
}
I have my cell observing an object, and calling setNeedsDisplay on my custom layer when it changes.
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
self.percentDone = (float)self.bytesSoFar/self.bytesTotal;
NSLog(@"Update");
[self.foregroundLayer setNeedsDisplay];
}];
}
Here's the problem I'm having: The download proceeds, the object being observed fires the observer (so observeValueForKeyPath is called) and setNeedsDisplay is called. I verified this by logging with NSLog messages.
But the drawing method:
- (void)drawLayer:(CALayer *)theLayer
inContext:(CGContextRef)theContext
{
NSLog(@"Drawing");
// Drawing happens here
}
What I'm seeing is that the drawing starts out okay - printing "Update" and "Drawing" interleaved - but after a short time, the "Drawing" stops and just the "Update" messages continue.
If I click in the image browser, or tap a key on the keyboard, the "Drawing" resumes for a short while, and then stops, back to just "Update".
It's like I need to trigger a repaint using the keyboard or mouse - the setNeedsDisplay isn't doing it - but I don't understand why. It does work for a short time, stops working, then only works while I'm providing mouse input.
This has me baffled. I'd appreciate any suggestions.
I didn't find the problem here, but I did find a solution.
Invalidating IKImageBrowserView cells doesn't cause them to be repainted because IKImageBrowserView, probably for performance, doesn't redraw cells unless their version changes.
Instead of invalidating the cell, I now increment the imageVersion returned by my IKImageBrowserItem, and then invalidate the IKImageBrowserView. This reliably redraws the item.