drawRect circle and animate size/color

后端 未结 1 1556
抹茶落季
抹茶落季 2020-12-07 09:46

I am drawing a circle in the -drawRect: method of my UIView using the standard CGContextFillEllipseInRect() code. However, I would lik

相关标签:
1条回答
  • 2020-12-07 10:31

    This is much simpler if you don't draw the circle in drawRect:. Instead, set up your view to use a CAShapeLayer, like this:

    @implementation PulseView
    
    + (Class)layerClass {
        return [CAShapeLayer class];
    }
    

    The system sends layoutSubviews to your view whenever it changes size (including when it first appears). We override layoutSubviews to set up the shape and animate it:

    - (void)layoutSubviews {
        [self setLayerProperties];
        [self attachAnimations];
    }
    

    Here's how we set the layer's path (which determines its shape) and the fill color for the shape:

    - (void)setLayerProperties {
        CAShapeLayer *layer = (CAShapeLayer *)self.layer;
        layer.path = [UIBezierPath bezierPathWithOvalInRect:self.bounds].CGPath;
        layer.fillColor = [UIColor colorWithHue:0 saturation:1 brightness:.8 alpha:1].CGColor;
    }
    

    We need to attach two animations to the layer - one for the path and one for the fill color:

    - (void)attachAnimations {
        [self attachPathAnimation];
        [self attachColorAnimation];
    }
    

    Here's how we animate the layer's path:

    - (void)attachPathAnimation {
        CABasicAnimation *animation = [self animationWithKeyPath:@"path"];
        animation.toValue = (__bridge id)[UIBezierPath bezierPathWithOvalInRect:CGRectInset(self.bounds, 4, 4)].CGPath;
        animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
        [self.layer addAnimation:animation forKey:animation.keyPath];
    }
    

    Here's how we animate the layer's fill color:

    - (void)attachColorAnimation {
        CABasicAnimation *animation = [self animationWithKeyPath:@"fillColor"];
        animation.fromValue = (__bridge id)[UIColor colorWithHue:0 saturation:.9 brightness:.9 alpha:1].CGColor;
        [self.layer addAnimation:animation forKey:animation.keyPath];
    }
    

    Both of the attach*Animation methods use a helper method that creates a basic animation and sets it up to repeat indefinitely with autoreverse and a one second duration:

    - (CABasicAnimation *)animationWithKeyPath:(NSString *)keyPath {
        CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:keyPath];
        animation.autoreverses = YES;
        animation.repeatCount = HUGE_VALF;
        animation.duration = 1;
        return animation;
    }
    
    0 讨论(0)
提交回复
热议问题