美文网首页
iOS 碎片动画简单实现

iOS 碎片动画简单实现

作者: 灯红酒绿映不出的落寞 | 来源:发表于2017-12-11 16:54 被阅读27次
未命名.gif

效果图先来Demo地址

生成的gif真是不敢恭维,如果读者有比较好的gif生成工具,还望告知与我。
碎片动画的大致原理。
1.返回的时候截取当前屏幕,
2.通过当前截取的视图,来做碎片动画,
思路清晰,直接开搞。这里通过分类方式实现,首先创建分类 46E998A4-C9B0-4EEA-9696-3F71A3FE788D.png
点击Next
4E276709-02D3-48BB-898F-BA8499427E7F.png
命名就随便来了,继续Next创建好我们的分类
这里不得不先说一下,我们需要用到的系统的几个方法
CAF76C39-E654-4866-BAE8-79429EFF785D.png
看不懂的小伙伴自己动手打开Xcode。google翻译一波奥,这里主要说下以上会用到的几个方法
* Creating snapshots from existing snapshots (as a method to duplicate, crop or create a resizable variant)
 is supported. In cases where many snapshots are needed, creating a snapshot from a common superview and making subsequent snapshots from it can be more performant.
 Please keep in mind that if 'afterUpdates' is YES, the original snapshot is committed and any changes made to it, not the view originally snapshotted, will be included.
 */
- (nullable UIView *)snapshotViewAfterScreenUpdates:(BOOL)afterUpdates NS_AVAILABLE_IOS(7_0);

以上这个方法就是我们会用到饿截图方法。
- (nullable UIView *)resizableSnapshotViewFromRect:(CGRect)rect afterScreenUpdates:(BOOL)afterUpdates withCapInsets:(UIEdgeInsets)capInsets NS_AVAILABLE_IOS(7_0);  
// Resizable snapshots will default to stretching the center
// Use this method to render a snapshot of the view hierarchy into the current context.
 Returns NO if the snapshot is missing image data,
 YES if the snapshot is complete.
 Calling this method from layoutSubviews while the current transaction is committing will capture what is currently displayed regardless if afterUpdates is YES.


resizableSnapshotViewFromRect 这个方法就是根据frame 去截图
到这里,既然我们能根据frame去截图,下边直接进入正题
考虑封装性,外部调用方法,这里直接分类里开出一个方法供外部使用.h代码
90FAFA47-0D81-40D5-8F63-0901403C4C7A.png
/*
 pop返回碎片动画
 @property  调用示例
 
 [[UIApplication sharedApplication].keyWindow addSubview:self.view];
 [self.view fragmenttationAnimation];
 [self.navigationController popViewControllerAnimated:NO];
 
 */
- (void)fragmenttationAnimation;

.m里边实现方法
image.png
image.png
- (void)fragmenttationAnimation{
    // 先截图
    UIView *snapView = [self snapshotViewAfterScreenUpdates:YES];
    // 隐藏容器中的子控件
    for (UIView *view in self.subviews) {
        view.hidden = YES;
        
    }
    
    //self.backgroundColor = [[UIColor purpleColor]colorWithAlphaComponent:0];
    // 保存x坐标的数组
    NSMutableArray *xArray = [[NSMutableArray alloc] init];
    // 保存y坐标
    NSMutableArray *yArray = [[NSMutableArray alloc] init];
    
    for (NSInteger i = 0; i < self.bounds.size.width; i = i + 10) {
        @autoreleasepool{
            [xArray addObject:@(i)];
        }
    }
    for (NSInteger i = 0; i < self.bounds.size.height; i = i + 10) {
        @autoreleasepool{
            [yArray addObject:@(i)];
        }
    }
    
    
    //这个保存所有的碎片
    NSMutableArray *snapshots = [[NSMutableArray alloc] init];
    for (NSNumber *x in xArray) {
        
        for (NSNumber *y in yArray) {
            @autoreleasepool{
                CGRect snapshotRegion = CGRectMake([x doubleValue], [y doubleValue], 10, 10);
                
                // resizableSnapshotViewFromRect 这个方法就是根据frame 去截图
                UIView *snapshot      = [snapView resizableSnapshotViewFromRect:snapshotRegion afterScreenUpdates:NO withCapInsets:UIEdgeInsetsZero];
                snapshot.frame        = snapshotRegion;
                [self addSubview:snapshot];
                [snapshots         addObject:snapshot];
            }

        }
    }
    
    
    [UIView animateWithDuration:1.5
                          delay:0
                        options:UIViewAnimationOptionCurveLinear
                     animations:^{
                         //  self.backgroundColor = [[UIColor blackColor]colorWithAlphaComponent:0.05];
                         for (UIView *view in snapshots) {
                             @autoreleasepool{
                                 view.frame = CGRectOffset(view.frame, [self randomRange:200 offset:-100], [self randomRange:200 offset:self.frame.size.height/2]);
                                 self.alpha = 0.1;
                             }

                         }
                         
                     }
                     completion:^(BOOL finished) {
                         for (UIView *view in snapshots) {
                             [view removeFromSuperview];
                         }
                         [self removeFromSuperview];                         
                     }];
    
    
}
- (CGFloat)randomRange:(NSInteger)range offset:(NSInteger)offset{
    
    return (CGFloat)(arc4random()%range + offset);
}


代码基本注释都有,有不懂的小伙伴可以私信,或者评论
调用示例
/*
 pop返回碎片动画
 @property  调用示例
 
 [[UIApplication sharedApplication].keyWindow addSubview:self.view];
 [self.view fragmenttationAnimation];
 [self.navigationController popViewControllerAnimated:NO];
 
 */

Demo地址

相关文章

网友评论

      本文标题:iOS 碎片动画简单实现

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