CALayer delegate method drawLayer not getting call

2020-07-03 03:57发布

问题:

My object a sub class of NSObject has CALayer instance variable. I use it for drawing and caching content with its delegate set to my object.

But for some reason drawLayer:inContext: method NEVER gets called. Whereas actionForLayer:forKey: delegate method does get called implying the delegate is getting set properly with layer.delegate = self in the object's init method.

Any suggestions on what is preventing my layer drawing method drawLayer:inContext: from getting called ?

I am called the [layer setNeedDisplay] often. So I guess it is some fundamental error.

回答1:

drawLayer:inContext: won't get called if your frame is CGRectZero or offscreen. Also, if your CALayer isn't attached to an existing onscreen layer, it will never draw, no matter how many times you call setNeedsDisplay



回答2:

Implement an empty drawRect:

- (void)drawRect:(CGRect)rect {
}

Taken from the ZoomingPDFViewer project:-

UIView uses the existence of -drawRect: to determine if it should allow its CALayer to be invalidated, which would then lead to the layer creating a backing store and -drawLayer:inContext: being called. By implementing an empty -drawRect: method, we allow UIKit to continue to implement this logic, while doing our real drawing work inside of -drawLayer:inContext:



回答3:

The layer object's setNeedsDisplay must be called. Simply adding the layer as a sublayer does not do that for you. Got this from Ray Wenderlich's CALayer tutorial.



回答4:

If you're eventually using the CALayer with a UIView then the delegate must be the view object itself:

From the iOS CALayer documentation:

"In iOS, if the layer is associated with a UIView object, this property must be set to the view that owns the layer."



回答5:

If you have a multi-threaded app where background processing drives the need to update the CALayer, you must call setNeedsDisplay in the main thread