Search code examples
iosobjective-cuiviewcore-animation

How to animate a swell and color change for a custom view selection?


I have hierarchy of custom UIView objects. The leaf views are selectable. They have an isSelected property on them. When this is set to YES, the effect I want is for the view to change to my "selected" color immediately, and then to temporarily swell in size and then return to its original size. I thought the following code would do the trick:

self.backgroundColor = [UIColor colorWithRed: 0 green: 0.5 blue: 1 alpha: 1];
CGRect currentFrame = self.frame;
CGRect bigFrame = CGRectInset(currentFrame, -50, -50);
[UIView animateWithDuration: 0.4 animations:^{
    self.frame = bigFrame;
} completion:^(BOOL finished) {
    if (finished ) {
        [UIView animateWithDuration: 0.4 animations:^{
            self.frame = currentFrame;
        }];
    }
}];

I've exaggerated the time and displacement here, because I was trying to see what's really happening. What happens, is that the color changes seems to be animated, so it slowly changes from its default whiteness of 0.93 to my blue. Furthermore, it doesn't grow in size. It just seems to translate down and to the right by the inset amount, and then return to the normal spot (rather than grow in all directions).

What am I missing?


Solution

  • Use keyframe animations:

    CAKeyframeAnimation *bounceAnimation = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale"];
    // 200 is example side of the big view, but you can apply any formula to it. For example relative to superview, or screen bounds
    CGFloat multiplier = 200 / MAX(self.frame.size.height, self.frame.size.width)
    bounceAnimation.values =
    @[@(1 - 0.1 * multiplier, 
      @(1 + 0.3 * multiplier), 
      @(1 + 0.1 * multiplier,
      @1.0];
    bounceAnimation.duration = 0.25;
    bounceAnimation.removedOnCompletion = YES;
    bounceAnimation.fillMode = kCAFillModeForwards;
    [self.layer addAnimation:bounceAnimation forKey:@"bounceAnimation"];