动画效果:snapshotViewAfterScreenUpda

作者: mokong | 来源:发表于2016-01-28 10:36 被阅读3261次

    动画:
    复杂动画的实现:首先要拆分,明确你自己要实现的效果是什么,然后开始拆分,第一步实现什么,然后实现什么...,怎么样链接起来。把复杂的动画拆分成一个个小步骤,然后一步步实现就可以了。

    gif1

    snapshotViewAfterScreenUpdates(_:) 这个方法我在做拖拽tableView的item的时候(eg: SystemPreference)看到的,感觉用来做动画很好用。相当于截个图,然后拿着这个截图,实现各种动画效果。
    eg:

    1. 如果你是一个电商项目,将商品加入购物车,这个动画就可以用这个来实现(Ps:我记得京东还是淘宝久有这个效果,但是我却又找不到了),点击加入购物车,然后对商品生成一个快照,然后缩小移动到购物车(还可以加入旋转的动画),到购物车的位置,移除。Perfect!
    2. 我做的这个项目,读信的过程就是用这个效果实现,点击信封,然后生成快照,然后快照位移到屏幕中间,消失,然后信封详情出现。
    image1

    实现

    首先,定义动画效果的实现:

    1. 查看信件:a. 点击信件,然后生成信件快照; b.信件快照位移到屏幕中央;同时信件详情出现,信件快照消失;
    2. 关闭详情:a. 点击空白处,生成信件详情快照和信件快照;信件快照起始状态隐藏;b.信件详情快照慢慢变小到和信件快照同样大小;然后消失,信件快照显示;c:信件快照位移到信件的位置,然后消失;

    代码

    /**
     *  @brief 返回对应view的snapshot
     *
     *  @param inputView 输入的view
     *
     *  @return 返回的snapshot
     */
    - (UIView *)customSnapshotFromView:(UIView *)inputView {
        UIView *snapshot = [inputView snapshotViewAfterScreenUpdates:YES];
        snapshot.layer.masksToBounds = YES;
        snapshot.layer.cornerRadius = 0.0;
        snapshot.layer.shadowOffset = CGSizeMake(-5.0, 0.0);
        snapshot.layer.shadowRadius = 5.0;
        snapshot.layer.shadowOpacity = 0.4;
        return snapshot;
    }```
    
    > 关闭详情
    
    ```Objective-C
    
    /**
     *  动画 关闭详情
     *
     *  @param sourceView      起始位置的view
     *  @param destinationView 终点位置的view
     *  @param animateFinished 动画结束的回调
     */
    - (void)animateView:(UIView *)sourceView
                 toView:(UIView *)destinationView
               finished:(AnimateFinished)animatedFinished
    {
        /**
         *  逻辑:1. 得到两个view的snapshot, sourcesnapshot/destinationsnapshot
         *       2. 然后,设置destinationsnapshot的中心为整个view的中心,设置为透明(即不显示)
         *       3. 隐藏当前sourceView,第一个动画实现,sourceViewsnapshot大小变为destinationsnapshot的大小,然后隐藏,同时显示destinationsnapshot
         *       4. 第二个动画实现:destinationsnapshot移动回对应位置,然后隐藏
         */
        
        // 1
        UIView *sourceSnapshot = [self customSnapshotFromView:sourceView];
        UIView *destinationSnapshot = [self customSnapshotFromView:destinationView];
        
        // 2
        CGPoint viewCenter = self.view.center;
        CGPoint destinationCenter = destinationView.center;
        destinationSnapshot.center = viewCenter;
        destinationSnapshot.alpha = 1.0;
        [self.view addSubview:sourceSnapshot];
        [self.view addSubview:destinationSnapshot];
        
        // 3
        sourceView.hidden = YES;
        [UIView animateWithDuration:0.5
                         animations:^{
                             sourceSnapshot.transform = CGAffineTransformMakeScale(1.05, 1.05);
                             sourceSnapshot.alpha = 0.98;
                             sourceSnapshot.frame = destinationSnapshot.frame;
                         } completion:^(BOOL finished) {
                             
                             self.alphaView.hidden = YES;
                             destinationSnapshot.alpha = 0.98;
                             [sourceSnapshot removeFromSuperview];
                             
                             // 4
                             [UIView animateWithDuration:0.5
                                              animations:^{
                                                  destinationSnapshot.center = destinationCenter;
                                                  destinationSnapshot.transform = CGAffineTransformIdentity;
                                              } completion:^(BOOL finished) {
                                                  [destinationSnapshot removeFromSuperview];
                                                  animatedFinished();
                                              }];
                         }];
        
    }```
    
    > 查看详情
    
    ```Objective-C
    
    /**
     *  动画 查看详情
     *
     *  @param viewToshow      要展示的view
     *  @param currentView     起始的view
     *  @param animateFinished 动画结束的回调
     */
    - (void)showView:(UIView *)viewToshow
            withView:(UIView *)currentView
            finished:(Finished)animateFinished
    {
        // Taking a snapshot of the selected row using helper method
        UIView *snapShot = [self customSnapshotFromView:currentView];
        
        // Add the snapshot as a subview, centered cell's center
        CGPoint viewCenter = self.view.window.center;
        CGPoint cellCenter = currentView.center;
        snapShot.center = cellCenter;
        snapShot.alpha = 0.0;
        snapShot.backgroundColor = [UIColor whiteColor];
        
        [self.view addSubview:snapShot];
        [UIView animateWithDuration:0.5 animations:^{
            snapShot.transform = CGAffineTransformMakeScale(1.05, 1.05);
            snapShot.alpha = 0.98;
        } completion:^(BOOL finished) {
            [UIView animateWithDuration:0.5 animations:^{
                snapShot.center = viewCenter;
                snapShot.transform = CGAffineTransformIdentity;
            } completion:^(BOOL finished) {
                self.alphaView.hidden = NO;
                viewToshow.hidden = NO;
                [snapShot removeFromSuperview];
                animateFinished();
            }];
        }];
    }```
    
    > Ps: 也许会好奇,为什么查看和关闭会是两个不同的部分?可以再回头查看一下分割的动画,发现过程其实是不一样的,查看详情比关闭少了一个步骤。
    代码:[AnimateSnapshotView](https://github.com/mokong/AnimateSnapShotView)

    相关文章

      网友评论

      • helinyu:现在好像这个方法截图不了了,都是空白?为什么,好像用了你的代码进行测试,也会不可以
        helinyu:我觉得也是iOS 10的问题,出现了改变。
        mokong:@谷寒,@qBryant,不好意思,我刚看到,试了一下发现,确实不可用了,好像是iOS10的问题,搜了之后发现可以用UIGraphicsGetImageFromCurrentImageContext作为替代,具体的等我晚上回去实验过之后,在交流:smile:
        qBryant:我用snapshotViewAfterScreenUpdates这个截图也是白色,不知道啥情况

      本文标题:动画效果:snapshotViewAfterScreenUpda

      本文链接:https://www.haomeiwen.com/subject/oqwdkttx.html