天天看點

CALayer的隐式動畫

何為隐式動畫

隐式動畫就是直接改變layer的一些屬性時,并沒有作動畫處理,layer會附帶有動畫效果,而不是直接瞬間變化,這個動畫時間預設是0.25秒。

layer的哪些屬性有隐式動畫

區分屬性是不是具有隐式動畫,要看屬性定義有沒有“Animatable”字樣。比如

/* The background color of the layer. Default value is nil. Colors
 * created from tiled patterns are supported. Animatable. */
@property(nullable) CGColorRef backgroundColor;
           

backgroundColor屬性的定義最後标明了Animatable,說明修改它的值會有預設動畫效果。

怎樣修改隐式動畫

一、通過CATransaction

在頁面上放了一個layer,通過點選button修改它的顔色

@property (nonatomic,strong) UIView     *backView;
@property (nonatomic,strong) CALayer    *colorLayer;
@property (nonatomic,strong) UIButton   *changeButton;

- (void)viewDidLoad {
    [super viewDidLoad];
    CGFloat kScreenWidth = [UIScreen mainScreen].bounds.size.width;
    _backView = [[UIView alloc] initWithFrame:CGRectMake(kScreenWidth/-, , , )];
    _backView.backgroundColor = [UIColor whiteColor];
    [self.view addSubview:_backView];

    _colorLayer = [CALayer layer];
    _colorLayer.frame = CGRectMake(, , , );
    _colorLayer.backgroundColor = [UIColor redColor].CGColor;
    _colorLayer.borderWidth = ;
    _colorLayer.borderColor = [UIColor blackColor].CGColor;
    _colorLayer.delegate = self;
    [_backView.layer addSublayer:_colorLayer];

    _changeButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [_changeButton addTarget:self action:@selector(changeColor) forControlEvents:UIControlEventTouchUpInside];
    _changeButton.frame = CGRectMake(, , , );
    [_changeButton setTitle:@"Change Color" forState:UIControlStateNormal];
    [_changeButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    _changeButton.titleLabel.font = [UIFont systemFontOfSize:];
    _changeButton.titleLabel.textColor = [UIColor blackColor];
    _changeButton.layer.cornerRadius = ;
    _changeButton.layer.borderWidth = ;
    _changeButton.layer.borderColor = [UIColor blackColor].CGColor;
    _changeButton.backgroundColor = [UIColor whiteColor];
    [_backView addSubview:_changeButton];
}

- (void)changeColor{
    _colorLayer.backgroundColor = [UIColor blueColor].CGColor;]
}
           

為了修改隐式動畫,我們對changeColor作修改

- (void)changeColor{
    [CATransaction begin];
    [CATransaction setAnimationDuration:2];
    _colorLayer.backgroundColor = [UIColor blueColor].CGColor;
    [CATransaction commit];
}
           

這樣點選改變顔色的隐式動畫的時間就被修改為2秒。

CATransaction還提供了禁用隐式動畫和設定完成動作等方法。

二、通過layer的actions屬性

CATransition *transition = [CATransition animation];
    transition.type = @"push";
    transition.subtype = @"fromLeft";
    _colorLayer.actions = @{@"backgroundColor":transition};
           

這樣在改變顔色的過程中就會附帶推進的動畫效果。

三、通過手動實作-actionForLayer:(CALayer )layer forKey:(NSString )event方法

_colorLayer.delegate = self;

- (nullable id<CAAction>)actionForLayer:(CALayer *)layer forKey:(NSString *)event{
    CABasicAnimation *animation = [CABasicAnimation animation];
    animation.keyPath = @"backgroundColor";
    animation.toValue = (__bridge id)[UIColor blueColor].CGColor;
    return animation;
}
           

UIView中的layer是沒有隐式動畫的

UIView關聯的layer的隐式動畫是被禁用的,是以如果想要通過改變view.layer的屬性來實作動畫是行不通的,隻能通過UIView動畫方法或者顯式的添加動畫來實作。