iOS Facebook 屏幕流动动画

1,129 阅读2分钟
最近在YT上看到一位大神写的个关于Facebook动画教程,尤其是这个屏幕动画(如下图)令我印象深刻。在他的代码下如此简单就可以实现,于是我整理了下他的教程,用Swift和OC分别做了个Demo。

源码-->FBScreenAnimation


22.gif

以下分别是Swift和OC写的Demo,并做了注释。有兴趣的学习下:

swift:

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        //每点击一次屏幕产生一组图片动画
        view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handelTap)))
    }
    func handelTap() {
        //循环10次
        (0...10).forEach { (_) in
            //生成动态视图
            generateAnimationViews()
        }
    }
    fileprivate func generateAnimationViews() {
        //drand48()的作用是产生[0,1]之间均匀分布的随机数
        let image = drand48() > 0.5 ? #imageLiteral(resourceName: "thumbsUp") : #imageLiteral(resourceName: "heart")
        let imageView = UIImageView(image: image)
        //产生20到38之间的随机数
        let dimension = 20 + drand48() * 19
        //定义图片frame
        imageView.frame = CGRect(x: 0, y: 0, width: dimension, height: dimension)
        //添加关键帧动画
        let animation = CAKeyframeAnimation(keyPath: "position")
        animation.path = customPath().cgPath
        animation.duration = 2 + drand48() * 3
        animation.fillMode = kCAFillModeForwards
        animation.isRemovedOnCompletion = false
        animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)
        //把图片关键帧动画路径上
        imageView.layer.add(animation, forKey: nil)
        //添加图片到视图
        view.addSubview(imageView)
    }
}
func customPath() -> UIBezierPath {
    let path = UIBezierPath()
    //起始点
    path.move(to: CGPoint(x: 0, y: 200))
    //终点
    let endPoint  = CGPoint(x: 500, y: 200)
    //随机值
    let randomYShift = 200 + drand48() * 250
    //设置2个控制点
    let cp1 = CGPoint(x: 100, y: 100 - randomYShift)
    let cp2 = CGPoint(x: 200, y: 300 + randomYShift)
    //曲线路径
    path.addCurve(to: endPoint, controlPoint1: cp1, controlPoint2: cp2)
    return path
}

objective-c:

- (void)viewDidLoad {
    [super viewDidLoad];
    //每点击一次屏幕产生一组图片动画
    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handleTap)];
    [self.view addGestureRecognizer:tapGesture];
}
-(void)handleTap{
    //循环10次
    for (NSInteger i = 0; i < 10; i++) {
        //生成动态视图
        [self gengerateAnimationViews];
    }
}
-(void)gengerateAnimationViews{
    UIImage *image = [UIImage imageNamed:drand48() > 0.5 ? @"thumbsUp" : @"heart"];
    UIImageView *imageView = [[UIImageView alloc]initWithImage:image];
    //drand48()的作用是产生[0,1]之间均匀分布的随机数
    //产生20到38之间的随机数
    NSInteger dimension = 20 + drand48() * 19;
    //定义图片frame
    imageView.frame = CGRectMake(0, 0, dimension, dimension);
    //添加关键帧动画
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    animation.path = [self customPath].CGPath;
    animation.duration = 2 + drand48() * 3;
    animation.fillMode = kCAFillModeForwards;
    animation.removedOnCompletion = NO;
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
    //把图片关键帧动画路径上
    [imageView.layer addAnimation:animation forKey:nil];
    //添加图片到视图
    [self.view addSubview:imageView];
}
-(UIBezierPath *)customPath {
    UIBezierPath *path = [[UIBezierPath alloc]init];
    //起始点
    [path moveToPoint:CGPointMake(0, 200)];
    //终点
    CGPoint endPoint = CGPointMake(500, 200);
    //随机值
    NSInteger randomYShift = 200 + drand48() * 250;
    //设置2个控制点
    CGPoint cp1 = CGPointMake(100, 100 - randomYShift);
    CGPoint cp2 = CGPointMake(200, 300 + randomYShift);
    //曲线路径
    [path addCurveToPoint:endPoint controlPoint1:cp1 controlPoint2:cp2];

    return path;
}

源码-->FBScreenAnimation