Unable to get CALayer to update its drawLayer: DURING border animation

I am trying to animate custom borders of a UIView while keeping my layer the same size as its parent view. To do this, I'm trying to animate the borders of the layers next to my parent view. I need a layer to call drawLayer: withContext AS - its animation, so my own drawing will correctly resize along with the borders.

drawLayer is called correctly and draws correctly before the animation starts. But I can’t get the layer to call the drawLayer method on EVERY step of border animation. Instead, he simply calls it ONCE, immediately moving to the “end borders” in the last frame of the animation.

// self.bg is a property pointing to my custom UIView
self.bg.layer.needsDisplayOnBoundsChange = YES;
self.bg.layer.mask.needsDisplayOnBoundsChange = YES;

[UIView animateWithDuration:2 delay:0 options:UIViewAnimationOptionCurveEaseOut|UIViewAnimationOptionAutoreverse|UIViewAnimationOptionRepeat animations:^{

    [CATransaction begin];
    self.bg.layer.bounds = bounds;
    self.bg.layer.mask.bounds = bounds;
    [CATransaction commit];

    self.bg.bounds = bounds;
} completion:nil];

AS ( )? ?

+5
3

...

, Core Animation supercool, , . , , CALayer a thickness. Core Animation...

CABasicAnimation* ba = [CABasicAnimation animationWithKeyPath:@"thickness"];
ba.toValue = @10.0f;
ba.autoreverses = YES;
[lay addAnimation:ba forKey:nil];

... , drawInContext: drawLayer:... , thickness ( ).

, , . , :

https://github.com/mattneub/Programming-iOS-Book-Examples/tree/master/ch17p498customAnimatableProperty

( ) :

http://www.apeth.com/iOSBook/ch17.html#_making_a_property_animatable

+3

, , , , , .

layer, ( ), .

:

CALayer *presentationLayer = (CALayer *)[self.bg.layer presentationLayer];
...

drawLayer:withContext, , , , .

+1

-, ( ) . , drawLayer: inContext: . , , needsDisplayOnBoundsChange == YES.

( Mac) , .

// My Nib contains one view and one button. 
// The view has a MPView class and the button action is resizeWindow:

@interface MPView() {
    CAShapeLayer     *_hostLayer;
    CALayer          *_outerLayer;
    CAShapeLayer     *_innerLayer;
}
@end

@implementation MPView

- (void)awakeFromNib
{
    [CATransaction begin];
    [CATransaction setDisableActions:YES];

    _hostLayer = [CAShapeLayer layer];
    _hostLayer.backgroundColor = [NSColor blackColor].CGColor;
    _hostLayer.borderColor = [NSColor redColor].CGColor;
    _hostLayer.borderWidth = 2;
    _hostLayer.needsDisplayOnBoundsChange = YES;
    _hostLayer.delegate = self;
    _hostLayer.lineWidth = 4;
    _hostLayer.strokeColor = [NSColor greenColor].CGColor;
    _hostLayer.needsDisplayOnBoundsChange = YES;

    self.layer = _hostLayer;
    self.wantsLayer = YES;

    [CATransaction commit];

    [self.window setFrame:CGRectMake(100, 100, 200, 200) display:YES animate:NO];
}

- (void) drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx
{
    if (layer == _hostLayer) {

        CGSize size = layer.bounds.size;
        CGMutablePathRef path = CGPathCreateMutable();

        CGPathMoveToPoint(path, NULL, 0, 0);
        CGPathAddLineToPoint(path, NULL, size.width, size.height);

        _hostLayer.path = path;

        CGPathRelease(path);
    }
}

- (IBAction)resizeWindow:(id)sender
{
    [self.window setFrame:CGRectMake(100, 100, 1200, 800) display:YES animate:YES];
}

@end
+1

All Articles