animating a custom CALayer property

2019-07-24 14:02发布

I'm trying to define an abstract layer property, angle, based on the existing layer property position. Basically it describes the orientation of the layer from the center of a circle. I did like the following:

@interface MenuItemLayer : CALayer
  @property CGFloat angle;
@end

@implementation MenuItemLayer

+ (BOOL)needsDisplayForKey: (NSString*)key {
  if ([key isEqualToString: @"angle"]) return YES;
  return [super needsDisplayForKey: key];
}

- (void)drawInContext: (CGContextRef)context {
  [self renderInContext: context];
}

- (CGFloat)angle {
  CGPoint center = self.superlayer.center;
  CGPoint pos = self.position;
  return atan2f(pos.x - center.x, center.y - pos.y);
}

- (void)setAngle: (CGFloat)angle {
  CGPoint center = self.superlayer.center;
  CGFloat radius = 100;
  [CATransaction begin];
  [CATransaction setDisableActions: YES];
  self.position = CGPointMake(center.x + radius * sinf(angle),
                              center.y - radius * cosf(angle));
  [CATransaction commit];
}

@end


It works fine when I manually set the value with setAngle:, but the problem is that when I try to animate it with a CABasicAnimation, the view sustained by the MenuItemLayer doesn't move at all and stays at its original position, while I can see that setValue: and drawInContext: get called normally along with the progress of the animation and so the position property of the presentation layer get updated.

Anyone has some clues? Thanks!



----

Just noticed the following comment in the doc:

renderInContext:
This method renders directly from the layer tree, ignoring any animations added to the render tree. Renders in the coordinate space of the layer.


Does this mean that renderInContext: will always use model layer to render the image even in our case where the receiver of the drawInContext: method is a presentation layer? Could this be the cause of the problem? If so, should I always manually translate the layer to the right location represented by the presentation layer?

1条回答
我想做一个坏孩纸
2楼-- · 2019-07-24 14:34

What do you intend this to do?

- (void)drawInContext: (CGContextRef)context {
  [self renderInContext: context];
}

What happens when you comment it out? I find that -renderInContext is most commonly used to render into a context for the sake of saving it as an image so this looks strange to me. A basic animation should be able to animate your property without a problem but overriding -drawInContext seems like it would only make sense if you're planning to do some custom drawing with CG.

查看更多
登录 后发表回答