Why can't I animate a custom property on the UIView default backgorund layer?

别来无恙 提交于 2021-02-11 05:52:44

问题


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?

来源:https://stackoverflow.com/questions/62421716/why-cant-i-animate-a-custom-property-on-the-uiview-default-backgorund-layer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!