Using CALayer Delegate

前端 未结 8 1091
滥情空心
滥情空心 2020-12-02 08:44

I have a UIView whose layers will have sublayers. I\'d like to assign delegates for each of those sublayers, so the delegate method can tell the layer what to draw. My que

相关标签:
8条回答
  • 2020-12-02 09:17

    I prefer the following solution. I would like to use the drawLayer:inContext: method of the UIView to render a subview that I might add without adding extra classes all over the place. My solution is as follows:

    Add the following files to your project:

    UIView+UIView_LayerAdditions.h with contents:

    @interface UIView (UIView_LayerAdditions)
    
    - (CALayer *)createSublayer;
    
    @end
    

    UIView+UIView_LayerAdditions.m with contents

    #import "UIView+UIView_LayerAdditions.h"
    
    static int LayerDelegateDirectorKey;
    
    @interface LayerDelegateDirector: NSObject{ @public UIView *view; } @end
    @implementation LayerDelegateDirector
    
    - (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx
    {
        [view drawLayer:layer inContext:ctx];
    }
    
    @end
    
    @implementation UIView (UIView_LayerAdditions)
    
    - (LayerDelegateDirector *)director
    {
        LayerDelegateDirector *director = objc_getAssociatedObject(self, &LayerDelegateDirectorKey);
        if (director == nil) {
            director = [LayerDelegateDirector new];
            director->view = self;
            objc_setAssociatedObject(self, &LayerDelegateDirectorKey, director, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
        }
        return director;
    }
    
    - (CALayer *)createSublayer
    {
        CALayer *layer = [CALayer new];
        layer.contentsScale = [UIScreen mainScreen].scale;
        layer.delegate = [self director];
        [self.layer addSublayer:layer];
        [layer setNeedsDisplay];
        return layer;
    }
    
    @end
    

    Now add the header to your .pch file. If you add a layer using the createSublayer method, it will automagically show up without bad allocs in the override to drawLayer:inContext:. As far as I know the overhead of this solution is minimal.

    0 讨论(0)
  • 2020-12-02 09:24

    A note regarding "helper" classes for use as a layer's delegate (with ARC at least):

    Make sure you store a "strong" reference to your alloc/init'd helper class (such as in a property). Simply assigning the alloc/init'd helper class to the delegate seems to cause crashes for me, presumably because mylayer.delegate is a weak reference to your helper class (as most delegates are), so the helper class gets freed up before the layer can use it.

    If I assign the helper class to a property, then assign it to the delegate, my weird crashes go away, and things behave as expected.

    0 讨论(0)
提交回复
热议问题