开发者

Returning NSNull from actionForLayer:forKey

开发者 https://www.devze.com 2022-12-30 09:14 出处:网络
If I implement the CALayer delegate method actionForLayer:forKey I can return 开发者_Go百科[NSNull null] to force the CALayer to not animate any changes. Unfortunately, [NSNull null] doesn\'t implemen

If I implement the CALayer delegate method actionForLayer:forKey I can return 开发者_Go百科[NSNull null] to force the CALayer to not animate any changes. Unfortunately, [NSNull null] doesn't implement the CAAction delegate and XCode kicks out the following warning:

warning: class 'NSNull' does not implement the 'CAAction' protocol

Here is the method code:

- (id<CAAction>)actionForLayer:(CALayer *)theLayer
                        forKey:(NSString *)theKey {
 //This disables the animations when moving things around
 //Also, don't animate the selection box. It was doing weird things
 if(undoGroupStarted || theLayer == self.selectionBox) {
  return [NSNull null];
 } else {
  return nil;
 }
}

Am I doing something wrong? Is returning [NSNull null] bad behavior? If so, what is another way to do what I am trying to do here? If not, how do I make the compiler happy?


The "CoreAnimation Programming Guide" section Defined Search Pattern for Action Keys addresses this. They CALayer delegate can return nil to specify that it doesn't handle the action, but that the search should continue. It can also return [NSNull null] to specify that the action should not be handled (that is, the search should stop).

In the CALayer header, you'll see a bit more detail about how this is handled:

If any of these steps results in a non-nil action object, the following steps are ignored. If the final result is an instance of NSNull, it is converted to `nil'.

To make the compiler accept this, you can simply cast:

return (id <CAAction>)[NSNull null]; // Prevent the action from animating


Judging by Apple's CAAction documentation, the only built-in class that implements the CAAction protocol is CAAnimation (and its subclasses, of course). The compiler is expecting a return value that implements CAAction, so yes, returning [NSNull null] will not work. Do you really need to use this delegate method, as opposed to removing animations from the layer using [layer removeAllAnimations] or [layer removeAnimationForKey:]?

It seems wasteful, but if you absolutely have to use the delegate method, perhaps you could return a "blank" animation object:

return [CAAnimation animation];

Also, do you need to disable this animation permanently, or only in specific circumstances? If you don't need to permanently override the animation, you can use a CATransaction to disable animation for individual method calls, as documented here in the Core Animation Programming Guide.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号