美文网首页v2panda的技术专题iOS工作系列干货
一个发布界面动画效果的实现

一个发布界面动画效果的实现

作者: Tuberose | 来源:发表于2015-11-15 02:00 被阅读6198次
    • 做一个�类似新浪微博式样的发布界面动画
    • githubi地址:PublishAnimation
    • 可以看得出来这个动画虽然是一点一点执行的,但是你一点击加号按钮,就立马有个蒙版盖在上面
      • 要实现这个有三种方案:
        • 1.拿到这个TabBarController的View,然后addSubViews,加一个View上去
        • 2.拿到Window,然后addSubViews,加一个View上去
        • 3.直接modal出来(只是在印象中,modal出来是有一个默认的动画的,但是我们只要传参数animated的时候给一个NO的参数,就没有动画效果了)
    • 既然这样我们还是选择modal出来。而且这个动画里面的逻辑有点多,所以我们给它一个控制器去管理算了
    • 先创建CYPublishViewController,并勾选Xib
      • 有一点得注意:Xib的宽高是(600,600),并不是我们最终要显示的宽高
      • 我们的View是(375 ,600),他们是有差别的,要注意细节

    • ViewDidLoad:方法是View刚刚加载完,你的View是从Xib加载的,从Xib刚刚加载完的View它的宽高是和我们屏幕显示出来的View不一样的
    • 所以从Xib描述控制器的View的时候,你千万要小心这个问题,你在那里拿到的控制器的View的宽高有时候不是最终的
      • 但是Storybard里面加载是不会这样的事情发生的,因为它会自动调整好子控件的位置,这是Storybard较Xib先进的地方
    • 但是控制器也提供了这么一个方法,专门去布局控制器里面View的子控件,叫做ViewDidLayoutSubviews方法中
    • 这里有一种开发的模式:
      • 你可以在ViewDidLoad:方法先添加,然后在ViewDidLayoutSubviews方法中再布局--这种开发模式也必须保证控制器里面有属性
      • 但是我们要做动画还是不在这里做了

    • 有一种添加\布局子控件的方法
      • 1.在viewDidLoad方法中创建、添加子控件
      • 2.在viewDidLayoutSubviews方法中布局子控件

    • 在Xib中布局好imageView背景图片以及取消按钮
    • 从CYTabBar的publishClick:方法中modal出发布界面的控制器
      • �拿到窗口的根控制器,才能在这里modal出来
    - (void)publishClick
    {
        CYPublishViewController *publish = [[CYPublishViewController alloc] init];
        [self.window.rootViewController presentViewController:publish animated:NO completion:nil];
    }
    

    • 对应里面的动画,我们肯定用代码去实现,而不用Xib,因为Xib里面的东西是固定死的,里面往下掉的按钮,写个for循环就搞定了
    • 对于动态的东西,我们还是用代码实现


    • 而且对于做这种动画的效果,我们先不要考虑动画,先将画面里面的东西固定好,这样都能做出来了,那么我们只要调整它们一开始的位置在屏幕外面就可以了

    • 屏幕尺寸的宽和高会经常用到,所以写入到PCH文件中
    // 屏幕尺寸
    #define CYScreenH [UIScreen mainScreen].bounds.size.height
    #define CYScreenW [UIScreen mainScreen].bounds.size.width
    

    • 由图片我们分析:
      • 先设置上面的标语
    /** 标语 */
    @property (nonatomic, weak) UIImageView *sloganView;
    
    - (void)setupSloganView
    {
        CGFloat sloganY = CYScreenH * 0.2;
    
        // 添加
        UIImageView *sloganView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"app_slogan"]];
        sloganView.y = sloganY - CYScreenH;
        sloganView.centerX = CYScreenW * 0.5;
        [self.view addSubview:sloganView];
        self.sloganView = sloganView;
    
    • 六个按钮的设置
    • 我们为了简单起见,如果产品经理没有什么特殊要求的话,我们就让按钮的尺寸为屏幕宽度的三分之一,这样就不用去考虑间距问题了。它们就黏在一起了,这就好算了
    • 首先在CYPublishViewController.m文件中,设置按钮的排布(九宫格排布)
    - (void)setupButtons
    {
        // 数据
        NSArray *images = @[@"publish-video", @"publish-picture", @"publish-text", @"publish-audio", @"publish-review", @"publish-offline"];
        NSArray *titles = @[@"发视频", @"发图片", @"发段子", @"发声音", @"审帖", @"离线下载"];
    
        // 一些参数
        NSUInteger count = images.count;
        int maxColsCount = 3; // 一行的列数
        NSUInteger rowsCount = (count + maxColsCount - 1) / maxColsCount;
    
        // 按钮尺寸
        CGFloat buttonW = CYScreenW / maxColsCount;
        CGFloat buttonH = buttonW * 0.85;
        CGFloat buttonStartY = (CYScreenH - rowsCount * buttonH) * 0.5;
        for (int i = 0; i < count; i++) {
            // 创建、添加
            CYPublishButton *button = [CYPublishButton buttonWithType:UIButtonTypeCustom];
            button.width = -1; // 按钮的尺寸为0,还是能看见文字缩成一个点,设置按钮的尺寸为负数,那么就看不见文字了
            [button addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];
            [self.buttons addObject:button];
            [self.view addSubview:button];
    
            // 内容
            [button setImage:[UIImage imageNamed:images[i]] forState:UIControlStateNormal];
            [button setTitle:titles[i] forState:UIControlStateNormal];
    
            // frame
            CGFloat buttonX = (i % maxColsCount) * buttonW;
            CGFloat buttonY = buttonStartY + (i / maxColsCount) * buttonH;
    }
    
    • 你会发现设置后为这个样子:
    • 所以我们要调整按钮里面的图片和文字,因此我们自定义按钮CYPublishButton
    • 在CYPublishButton.m文件中布局好图片和文字的位置
    #import "CYPublishButton.h"
    
    @implementation CYPublishButton
    
        // 初始化
    - (instancetype)initWithFrame:(CGRect)frame
    {
        if (self = [super initWithFrame:frame]) {
            self.titleLabel.textAlignment = NSTextAlignmentCenter;
            self.titleLabel.font = [UIFont systemFontOfSize:15];
            [self setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
        }
        return self;
    }
    
    - (void)layoutSubviews
    {
        [super layoutSubviews];
    
        self.imageView.y = 0;
        self.imageView.centerX = self.width * 0.5;
    
        self.titleLabel.width = self.width;
        self.titleLabel.y = CGRectGetMaxY(self.imageView.frame);
        self.titleLabel.x = 0;
        self.titleLabel.height = self.height - self.titleLabel.y;
    }
    
    @end
    

    • 接下来就是动画的实现
      • 我们从图片中可以看出来这个动画里面的东西,是从上面往下面掉,按钮,一个个往下掉完后,标语再往下掉,而且有点弹簧效果
      • 其实这里也就是设置好它们Y值的位置就行了
    • 这里做这种弹簧式的动画有三种方法:
      • 1.让它们比如说按钮,从屏幕外先掉到一个下面的位置,然后再往上移一个位置,只是这里要给两个动画,这个方法比较笨
      • 2.用苹果自带的方法,也可以做弹簧效果


      • 3.用facebook出品的动画框架--pop,这个在一些公司里面也在用
        • 这里我们对比与苹果系统自带的核心动画
    • 苹果自带的核心动画,它是作用对象是在图层上面的


    • 苹果自带的核心动画,它是无法监听到动画的中间值
      • 比如说:X ==10-->X == 100.你是无法监听到中间的增长值的:你是无法知道动画的第0.5秒,第0.8秒,第1秒的时候它的值是多少的。也就是说X从10增长到100这个过程中,它的中间值你是拿不到的
      • 苹果自带的核心动画你只要把开始和结束的值传给它就行,中间的值它会给你算好,而且开始和结束他们值的增长和修改只是一个假象,你并不能拿到中间值
    • pop动画可以作用在任何对象上,而且可以监听到动画的中间值
      • 比如说:你可以让一个Money对象做动画,往1-->2-->3-->4-->5-->6-->7-->8。你能控制它弹回8-->7-->6-->5.也就是监听到中间值
    • pop的实现机制也不一样,它里面用了一个CADisplayLink的东西,自己内部搞了一套定时器,而且里面有许多的C++代码
    • 这里pop动画是让它作用在View上,而不是Layer上

      • 基本动画


      • 弹簧动画


    • 这里还有一个poppingLearnCube-iOS它不是框架,它是一个示例程序,它是教你怎么使用pop也是值得大家学习的,里面有许多好的动画效果,工作中是可以用得着的。你可以学习它是怎么写的,github上搜索Animation也会搜索出许多好的动画的框架或者是示例程序像:JHChainableAnimations

    • �还有awesome-ios-animation收集整理了下iOS平台下比较主流炫酷的�许多动画框架。反正对我们今后要做动画都有参考价值

     1.pop
     1> facebook出品的动画框架
     2> 动画能作用在任何对象上
     3> 能监听到动画的中间值
    
     2.Core Animation
     1> 苹果官方的动画框架
     2> 动画只能作用在CALayer上
     3> 无法监听到动画的中间值
    

    • 下面开始做动画

    • 按钮的动画:

    
        for (int i = 0; i < count; i++) {
            // 创建、添加
            CYPublishButton *button = [CYPublishButton buttonWithType:UIButtonTypeCustom];
            button.width = -1; // 按钮的尺寸为0,还是能看见文字缩成一个点,设置按钮的尺寸为负数,那么就看不见文字了
            [button addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];
            [self.buttons addObject:button];
            [self.view addSubview:button];
    
            // 内容
            [button setImage:[UIImage imageNamed:images[i]] forState:UIControlStateNormal];
            [button setTitle:titles[i] forState:UIControlStateNormal];
    
            // frame
            CGFloat buttonX = (i % maxColsCount) * buttonW;
            CGFloat buttonY = buttonStartY + (i / maxColsCount) * buttonH;
    
            // 动画
            POPSpringAnimation *anim = [POPSpringAnimation animationWithPropertyNamed:kPOPViewFrame];
            //  开始的位置(这里的宽高之所以不设置为0而保持和最终的位置一致,因为传0的话会发现按钮在慢慢变大,而我们需要是一个从上面掉下来的效果
            anim.fromValue = [NSValue valueWithCGRect:CGRectMake(buttonX, buttonY - CYScreenH, buttonW, buttonH)];
            //  最终的位置
            anim.toValue = [NSValue valueWithCGRect:CGRectMake(buttonX, buttonY, buttonW, buttonH)];
            anim.springSpeed = CYSpringFactor;
            anim.springBounciness = CYSpringFactor;
            // CACurrentMediaTime()获得的是当前时间
            anim.beginTime = CACurrentMediaTime() + [self.times[i] doubleValue];
            //  anim.beginTime = CACurrentMediaTime() + 0.1 * i;这里不这么写,是为了可以实现乱序的效果,哪个按钮先往下掉,可以由我们决定
            [button pop_addAnimation:anim forKey:nil];
        }
    }
    
    • anim.beginTime = CACurrentMediaTime() + 0.1 * i;这里不这么写,是为了可以实现乱序的效果,今后哪个按钮先往下掉,可以由我们决定
    • button.width = -1;
      • 尽管按钮的宽度高度为0,但是只要你给按钮设置了文字,所有按钮就挤成了一个点,它还是能显示一点点黑黑的文字的,这是按钮的一个特点,设置按钮的尺寸为负数,那么就看不见文字了,这是一个小细节

        UIImageView *sloganView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"app_slogan"]];
        sloganView.y = sloganY - CYScreenH;
        sloganView.centerX = CYScreenW * 0.5;
        [self.view addSubview:sloganView];
        self.sloganView = sloganView;
    
        CYWeakSelf;
        // 动画
        POPSpringAnimation *anim = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerPositionY];
        anim.toValue = @(sloganY);
        anim.springSpeed = CYSpringFactor;
        anim.springBounciness = CYSpringFactor;
        // CACurrentMediaTime()获得的是当前时间
        anim.beginTime = CACurrentMediaTime() + [self.times.lastObject doubleValue];
    
    • 这是标语的动画,给它先设置一个开始的Y值,让它在屏幕外开始做动画,因为它是最后出来的

    @interface CYPublishViewController ()
    /** 标语 */
    @property (nonatomic, weak) UIImageView *sloganView;
    /** 按钮 */
    @property (nonatomic, strong) NSMutableArray *buttons;
    
    /** 动画时间 */
    @property (nonatomic, strong) NSArray *times;
    @end
    
    @implementation CYPublishViewController
    
    - (NSMutableArray *)buttons
    {
        if (!_buttons) {
            _buttons = [NSMutableArray array];
        }
        return _buttons;
    }
    
    - (NSArray *)times
    {
        if (!_times) {
            CGFloat interval = 0.1; // 时间间隔
            _times = @[@(5 * interval),
                       @(4 * interval),
                       @(3 * interval),
                       @(2 * interval),
                       @(0 * interval),
                       @(1 * interval),
                       @(6 * interval)]; // 标语的动画时间
        }
        return _times;
    }
    
    • 设置时间间隔,按钮的时间间隔以及标语的时间间隔,标语加载时间是用self.times.lastObject doubleValue取数组中最后一个

    • 在CYPublishViewController.m文件中
    #import "CYPublishViewController.h"
    #import "CYPublishButton.h"
    #import "POP.h"
    
    static CGFloat const CYSpringFactor = 10;
    
    @interface CYPublishViewController ()
    /** 标语 */
    @property (nonatomic, weak) UIImageView *sloganView;
    /** 按钮 */
    @property (nonatomic, strong) NSMutableArray *buttons;
    
    /** 动画时间 */
    @property (nonatomic, strong) NSArray *times;
    @end
    
    @implementation CYPublishViewController
    
    - (NSMutableArray *)buttons
    {
        if (!_buttons) {
            _buttons = [NSMutableArray array];
        }
        return _buttons;
    }
    
    - (NSArray *)times
    {
        if (!_times) {
            CGFloat interval = 0.1; // 时间间隔
            _times = @[@(5 * interval),
                       @(4 * interval),
                       @(3 * interval),
                       @(2 * interval),
                       @(0 * interval),
                       @(1 * interval),
                       @(6 * interval)]; // 标语的动画时间
        }
        return _times;
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        // 禁止交互
        self.view.userInteractionEnabled = NO;
    
        // 按钮
        [self setupButtons];
    
        // 标语
        [self setupSloganView];
    }
    
    - (void)setupButtons
    {
        // 数据
        NSArray *images = @[@"publish-video", @"publish-picture", @"publish-text", @"publish-audio", @"publish-review", @"publish-offline"];
        NSArray *titles = @[@"发视频", @"发图片", @"发段子", @"发声音", @"审帖", @"离线下载"];
    
        // 一些参数
        NSUInteger count = images.count;
        int maxColsCount = 3; // 一行的列数
        NSUInteger rowsCount = (count + maxColsCount - 1) / maxColsCount;
    
        // 按钮尺寸
        CGFloat buttonW = CYScreenW / maxColsCount;
        CGFloat buttonH = buttonW * 0.85;
        CGFloat buttonStartY = (CYScreenH - rowsCount * buttonH) * 0.5;
        for (int i = 0; i < count; i++) {
            // 创建、添加
            CYPublishButton *button = [CYPublishButton buttonWithType:UIButtonTypeCustom];
            button.width = -1; // 按钮的尺寸为0,还是能看见文字缩成一个点,设置按钮的尺寸为负数,那么就看不见文字了
            [button addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];
            [self.buttons addObject:button];
            [self.view addSubview:button];
    
            // 内容
            [button setImage:[UIImage imageNamed:images[i]] forState:UIControlStateNormal];
            [button setTitle:titles[i] forState:UIControlStateNormal];
    
            // frame
            CGFloat buttonX = (i % maxColsCount) * buttonW;
            CGFloat buttonY = buttonStartY + (i / maxColsCount) * buttonH;
    
            // 动画
            POPSpringAnimation *anim = [POPSpringAnimation animationWithPropertyNamed:kPOPViewFrame];
            //  开始的位置(这里的宽高之所以不设置为0而保持和最终的位置一致,因为传0的话会发现按钮在慢慢变大,而我们需要是一个从上面掉下来的效果
            anim.fromValue = [NSValue valueWithCGRect:CGRectMake(buttonX, buttonY - CYScreenH, buttonW, buttonH)];
            //  最终的位置
            anim.toValue = [NSValue valueWithCGRect:CGRectMake(buttonX, buttonY, buttonW, buttonH)];
            anim.springSpeed = CYSpringFactor;
            anim.springBounciness = CYSpringFactor;
            // CACurrentMediaTime()获得的是当前时间
            anim.beginTime = CACurrentMediaTime() + [self.times[i] doubleValue];
            //  anim.beginTime = CACurrentMediaTime() + 0.1 * i;这里不这么写,是为了可以实现乱序的效果,哪个按钮先往下掉,可以由我们决定
            [button pop_addAnimation:anim forKey:nil];
        }
    }
    
    - (void)setupSloganView
    {
        CGFloat sloganY = CYScreenH * 0.2;
    
        // 添加
        UIImageView *sloganView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"app_slogan"]];
        sloganView.y = sloganY - CYScreenH;
        sloganView.centerX = CYScreenW * 0.5;
        [self.view addSubview:sloganView];
        self.sloganView = sloganView;
    
        CYWeakSelf;
        // 动画
        POPSpringAnimation *anim = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerPositionY];
        anim.toValue = @(sloganY);
        anim.springSpeed = CYSpringFactor;
        anim.springBounciness = CYSpringFactor;
        // CACurrentMediaTime()获得的是当前时间
        anim.beginTime = CACurrentMediaTime() + [self.times.lastObject doubleValue];
        [anim setCompletionBlock:^(POPAnimation *anim, BOOL finished) {
            // 开始交互
            weakSelf.view.userInteractionEnabled = YES;
        }];
        [sloganView.layer pop_addAnimation:anim forKey:nil];
    }
    
    - (void)buttonClick:(CYPublishButton *)button
    {
        CYLogFunc;
    }
    
    

    • 我们首先创建添加很多按钮,一添加按钮的时候设置它的宽度为负数,让它不会显示出黑点,然后设置图片和文字,然后让按钮从一个很上面的位置跑到它最终的位置,然后按钮的时间随着i值的不同,它弹出的先后时间也就不同
    • 按钮弹出完了后,接下里添加标语,标语是让它拿到最后的时间弹出来,最后弹出效果做出来了

    • 接下来是退出时候的动画,让它按照从前的顺序往下掉

    • 给取消按钮拖线

    • 然后给按钮创建一个数组,懒加载

    • 退出的动画用POPBasicAnimation就行了

    • 控制器销毁的时候要监听动画完毕时的状态用[anim setCompletionBlock:^(POPAnimation *anim, BOOL finished) {}

    • 有block的敌方最好加上CYWeakSelf;

    • 还有一个细节:两个动画如果一起执行,就会出现混乱,这样是完全不行的,你的控制用户是否能够点击

      • 在viewDidLoad:方法中,一进来,首先要控制View不能点击,只有控制它不能点击了,那么里面的六个按钮和标语都不能点击了。self.view.userInteractionEnabled = NO;
      • 在最后一个View标语动画加载完后,用户可以点击weakSelf.view.userInteractionEnabled = YES;
      • 同样一旦你点击了取消按钮,用户不能点击self.view.userInteractionEnabled = NO;
    • 而且这种效果,在一些应用中,你点击控制器蒙版的时候,这个整一个也会往下掉,所以在CYPublishViewController.m加一个方法

    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    {
        [self cancel];
    }
    
    - (IBAction)cancel {
        // 禁止交互
        self.view.userInteractionEnabled = NO;
    
        // 让按钮执行动画
        for (int i = 0; i < self.buttons.count; i++) {
            CYPublishButton *button = self.buttons[i];
    
            POPBasicAnimation *anim = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerPositionY];
            anim.toValue = @(button.layer.position.y + CYScreenH);
            // CACurrentMediaTime()获得的是当前时间
            anim.beginTime = CACurrentMediaTime() + [self.times[i] doubleValue];
            [button.layer pop_addAnimation:anim forKey:nil];
        }
    
        CYWeakSelf;
        // 让标题执行动画
        POPBasicAnimation *anim = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerPositionY];
        anim.toValue = @(self.sloganView.layer.position.y + CYScreenH);
        // CACurrentMediaTime()获得的是当前时间
        anim.beginTime = CACurrentMediaTime() + [self.times.lastObject doubleValue];
        [anim setCompletionBlock:^(POPAnimation *anim, BOOL finished) {
            [weakSelf dismissViewControllerAnimated:NO completion:nil];
        }];
        [self.sloganView.layer pop_addAnimation:anim forKey:nil];
    }
    
    

    • 在CYPublishViewController.m文件中
    #import "CYPublishViewController.h"
    #import "CYPublishButton.h"
    #import "POP.h"
    
    static CGFloat const CYSpringFactor = 10;
    
    @interface CYPublishViewController ()
    /** 标语 */
    @property (nonatomic, weak) UIImageView *sloganView;
    /** 按钮 */
    @property (nonatomic, strong) NSMutableArray *buttons;
    
    /** 动画时间 */
    @property (nonatomic, strong) NSArray *times;
    @end
    
    @implementation CYPublishViewController
    
    - (NSMutableArray *)buttons
    {
        if (!_buttons) {
            _buttons = [NSMutableArray array];
        }
        return _buttons;
    }
    
    - (NSArray *)times
    {
        if (!_times) {
            CGFloat interval = 0.1; // 时间间隔
            _times = @[@(5 * interval),
                       @(4 * interval),
                       @(3 * interval),
                       @(2 * interval),
                       @(0 * interval),
                       @(1 * interval),
                       @(6 * interval)]; // 标语的动画时间
        }
        return _times;
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        // 禁止交互
        self.view.userInteractionEnabled = NO;
    
        // 按钮
        [self setupButtons];
    
        // 标语
        [self setupSloganView];
    }
    
    - (void)setupButtons
    {
        // 数据
        NSArray *images = @[@"publish-video", @"publish-picture", @"publish-text", @"publish-audio", @"publish-review", @"publish-offline"];
        NSArray *titles = @[@"发视频", @"发图片", @"发段子", @"发声音", @"审帖", @"离线下载"];
    
        // 一些参数
        NSUInteger count = images.count;
        int maxColsCount = 3; // 一行的列数
        NSUInteger rowsCount = (count + maxColsCount - 1) / maxColsCount;
    
        // 按钮尺寸
        CGFloat buttonW = CYScreenW / maxColsCount;
        CGFloat buttonH = buttonW * 1.2;
        CGFloat buttonStartY = (CYScreenH - rowsCount * buttonH) * 0.5;
        for (int i = 0; i < count; i++) {
            // 创建、添加
            CYPublishButton *button = [CYPublishButton buttonWithType:UIButtonTypeCustom];
            button.width = -1; // 按钮的尺寸为0,还是能看见文字缩成一个点,设置按钮的尺寸为负数,那么就看不见文字了
            [button addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];
            [self.buttons addObject:button];
            [self.view addSubview:button];
    
            // 内容
            [button setImage:[UIImage imageNamed:images[i]] forState:UIControlStateNormal];
            [button setTitle:titles[i] forState:UIControlStateNormal];
    
            // frame
            CGFloat buttonX = (i % maxColsCount) * buttonW;
            CGFloat buttonY = buttonStartY + (i / maxColsCount) * buttonH;
    
            // 动画
            POPSpringAnimation *anim = [POPSpringAnimation animationWithPropertyNamed:kPOPViewFrame];
            anim.fromValue = [NSValue valueWithCGRect:CGRectMake(buttonX, buttonY - CYScreenH, buttonW, buttonH)];
            anim.toValue = [NSValue valueWithCGRect:CGRectMake(buttonX, buttonY, buttonW, buttonH)];
            anim.springSpeed = CYSpringFactor;
            anim.springBounciness = CYSpringFactor;
            // CACurrentMediaTime()获得的是当前时间
            anim.beginTime = CACurrentMediaTime() + [self.times[i] doubleValue];
            [button pop_addAnimation:anim forKey:nil];
        }
    }
    
    - (void)setupSloganView
    {
        CGFloat sloganY = CYScreenH * 0.2;
    
        // 添加
        UIImageView *sloganView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"app_slogan"]];
        sloganView.y = sloganY - CYScreenH;
        sloganView.centerX = CYScreenW * 0.5;
        [self.view addSubview:sloganView];
        self.sloganView = sloganView;
    
        CYWeakSelf;
        // 动画
        POPSpringAnimation *anim = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerPositionY];
        anim.toValue = @(sloganY);
        anim.springSpeed = CYSpringFactor;
        anim.springBounciness = CYSpringFactor;
        // CACurrentMediaTime()获得的是当前时间
        anim.beginTime = CACurrentMediaTime() + [self.times.lastObject doubleValue];
        [anim setCompletionBlock:^(POPAnimation *anim, BOOL finished) {
            // 开始交互
            weakSelf.view.userInteractionEnabled = YES;
        }];
        [sloganView.layer pop_addAnimation:anim forKey:nil];
    }
    
    - (void)buttonClick:(CYPublishButton *)button
    {
        CYLogFunc;
    }
    
    - (IBAction)cancel {
        // 禁止交互
        self.view.userInteractionEnabled = NO;
    
        // 让按钮执行动画
        for (int i = 0; i < self.buttons.count; i++) {
            CYPublishButton *button = self.buttons[i];
    
            POPBasicAnimation *anim = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerPositionY];
            anim.toValue = @(button.layer.position.y + CYScreenH);
            // CACurrentMediaTime()获得的是当前时间
            anim.beginTime = CACurrentMediaTime() + [self.times[i] doubleValue];
            [button.layer pop_addAnimation:anim forKey:nil];
        }
    
        CYWeakSelf;
        // 让标题执行动画
        POPBasicAnimation *anim = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerPositionY];
        anim.toValue = @(self.sloganView.layer.position.y + CYScreenH);
        // CACurrentMediaTime()获得的是当前时间
        anim.beginTime = CACurrentMediaTime() + [self.times.lastObject doubleValue];
        [anim setCompletionBlock:^(POPAnimation *anim, BOOL finished) {
            [weakSelf dismissViewControllerAnimated:NO completion:nil];
        }];
        [self.sloganView.layer pop_addAnimation:anim forKey:nil];
    }
    
    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    {
        [self cancel];
    }
    @end
    
    • 最后就实现了



    • 如果觉得对你有帮助,�Give me a star !

    相关文章

      网友评论

      本文标题:一个发布界面动画效果的实现

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