1

I want to animate the UIView default background layer. In viewDidLoad I'm adding my custom property to animate to the view with:

self.layer.delegate = self;
[self.layer setValue:0 forKey:@"value"];

as described here.

The setter method of the value to change looks like this and updates the added custom property on the background layer:

- (void)setValue:(NSInteger)value
{
  _value = value;
  [self.layer setValue:[NSNumber numberWithInteger:value] forKey:@"value"];
  [self setNeedsDisplay];
}

And in actionForLayer:forKey: overwritten in my view I'm returning an animation, as described here, which should animate from the current value to the new set value like this:

- (id<CAAction>)actionForLayer:(CALayer*)layer forKey:(NSString*)key
{
  if([key isEqualToString:@"value"])
  {
    CAAnimation* action = (CAAnimation*)[self actionForLayer:layer forKey:@"backgroundColor"];

    if(action != (CAAnimation*)[NSNull null])
    {

      CABasicAnimation* animation = [CABasicAnimation animation];
      animation.keyPath           = @"value";
      animation.fromValue         = [self.layer valueForKey:@"value"];
      animation.toValue           = [NSNumber numberWithInteger:_value];
      animation.beginTime         = action.beginTime;
      animation.duration          = action.duration;
      animation.speed             = action.speed;
      animation.timeOffset        = action.timeOffset;
      animation.repeatCount       = action.repeatCount;
      animation.repeatDuration    = action.repeatDuration;
      animation.autoreverses      = action.autoreverses;
      animation.fillMode          = action.fillMode;
      animation.timingFunction    = action.timingFunction;
      animation.delegate          = action.delegate;

      [self.layer addAnimation:animation forKey:@"value"];
    }
  }

  return [super actionForLayer:layer forKey:key];
}

And I draw my view content like this:

- (void)drawRect:(CGRect)rect
{
  CGContextRef context = UIGraphicsGetCurrentContext();
  CGContextClearRect(context, rect);
  [self drawARainbowUnicorn:context];;
}

From my view controller I do an block animation like this:

[UIView animateWithDuration:10.0 animations:
^{
  self->_myView.value = self->_myView.maximumValue;
}];

What I see is that the value always appears as animated on the final position. What I would expect is that the value would animate to that position in the given time.

All the examples I found add a separate layer to animate like this
or this or this and I'm aware of this StackOverflow question and some others I found.

I also had a look at this older sample project from Apple. They also create a CALayer subclass. But why is that needed?

I don't understand why the default background layer shouldn't do it as well. What do I miss here?

Bruno Bieri
  • 9,724
  • 11
  • 63
  • 92

0 Answers0