IOS实现碎片化动画详解

2020-01-15 17:30:45于海丽

maskView的子视图


maskView.backgroundColor = [UIColor clearColor];
UIView * sub1 = [[UIView alloc] initWithFrame: CGRectMake(0, 0, 20, 34)];
sub1.backgroundColor = [UIColor blackColor];
UIView * sub2 = [[UIView alloc] initWithFrame: CGRectMake(15, 18, 33, 40)];
sub2.backgroundColor = [UIColor blackColor];
[maskView addSubview: sub1];
[maskView addSubview: sub2];

要了解maskView的子视图对遮罩效果的影响,我们需要排除遮罩视图自身的干扰,因此maskView的背景颜色要设置成透明色

ios碎片化动画,ios,碎片动画效果,碎片效果
子视图对于遮罩的影响

可以看到,在遮罩自身透明的情况下,子视图也可以实现部分遮罩视图的效果。因此如果我们改变这些子视图的透明度的时候,遮罩效果也同样会发生改变

动画实现

回到上面展示的动画效果,我们可以看到图片被分割成多个长方形的小块逐渐消失。其中,垂直方向分为上下两份,横向大概有15份左右。因此我们需要现在maskView上面添加2*15个子视图,均匀分布。为了保证在动画的时候我们能依次实现子视图的隐藏,我们需要给子视图加上标识:


UIView * maskView = [[UIView alloc] initWithFrame: contentView.bounds];
const NSInteger horizontalCount = 15;
const NSInteger verticalCount = 2;
const CGFloat fadeWidth = CGRectGetWidth(maskView.frame) / horizontalCount;
const CGFloat fadeHeight = CGRectGetHeight(maskView.frame) / verticalCount;

for (NSInteger line = 0; line < horizontalCount; line ++) {
  for (NSInteger row = 0; row < verticalCount; row++) {
    CGRect frame = CGRectMake(line*fadeWidth, row*fadeHeight, fadeWidth, fadeHeight);
    UIView * fadeView = [[UIView alloc] initWithFrame: frame];
    fadeView.tag = [self viewTag: line*verticalCount+row];
    fadeView.backgroundColor = [UIColor whiteColor];
    [maskView addSubview: fadeView];
  }
}
contentView.maskView = maskView;

那么在动画开始的时候,我们需要依次遍历maskView上面的所有子视图,并且让他们依次执行动画:


for (NSInteger line = 0; line < horizontalCount; line ++) {
  for (NSInteger row = 0; row < verticalCount; row++) {
    NSInteger idx = line*verticalCount+row;
    UIView * fadeView = [contentView.maskView viewWithTag: [self viewWithTag: idx];
    [UIView animateWithDuration: fadeDuration delay: interval*idx options: UIViewAnimationOptionCurveLinear animations: ^{
      fadeView.alpha = 0;
    } completion: nil];
  }
}

我们在实现动画的同时,都应该考虑如何把动画封装出来方便以后复用。上面的碎片化动画完全可以作为UIViewcategory