除
Brad Larson的答案之外:对于自定义图层(由您创建),
您可以使用委托而不是修改图层的
actions
字典。这种方法更加动态,可能更具性能。它还允许禁用所有隐式动画,而无需列出所有可动画的键。
不幸的是,不可能将
UIView
用作自定义图层委托,因为每个
UIView
已经是其自己图层的委托。但是,您可以使用像这样的简单助手类:
@interface MyLayerDelegate : NSObject
@property (nonatomic, assign) BOOL disableImplicitAnimations;
@end
@implementation MyLayerDelegate
- (id<CAAction>)actionForLayer:(CALayer *)layer forKey:(NSString *)event
{
if (self.disableImplicitAnimations)
return (id)[NSNull null];
else return nil;
}
@end
使用方法(在视图内):
MyLayerDelegate *delegate = [[MyLayerDelegate alloc] init];
self.myLayerDelegate = delegate;
self.myLayer = [CALayer layer];
self.myLayer.delegate = delegate;
self.myLayerDelegate.disableImplicitAnimations = YES;
self.myLayer.position = (CGPoint){.x = 10, .y = 42};
self.myLayerDelegate.disableImplicitAnimations = NO;
self.myLayer.position = (CGPoint){.x = 0, .y = 0};
有时候,将视图控制器作为视图自定义子层的代理很方便;在这种情况下,不需要帮助类,您可以直接在控制器中实现
actionForLayer:forKey:
方法。
重要提示:不要尝试修改
UIView
底层图层的代理(例如启用隐式动画)-会发生糟糕的事情 :)
注意:如果您想要对层进行动画处理(而不是禁用动画),则将
[CALayer setNeedsDisplayInRect:]
调用放在
CATransaction
中没有用,因为实际的重绘可能会(并且很可能会)在稍后发生。好的方法是使用自定义属性,如
在这个答案中所述。
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ });
- Hashem Aboonajmi