• iOS动画——UIKit动画


    iOS动画

    iOS有很多动画技术,API主要分布在两个库中,一个是UIKit,另一个是CoreAnimation,先对UIKit动画做一下总结。

    UIKit动画

    在UIKit中,很多API都可以看到animated参数,表示是否动画显示,其实这是UIKit封装CoreAnimation后的结果。

    比如大家肯定都写过模态视图和导航控制器,他们在视图展示的时候都会有一个animated参数。

    [self.navigationController pushViewController:vc animated:YES];
    [self presentViewController:vc animated:YES completion:nil];

    这些动画除了系统提供,其实我们是可以自己定制的,这里先简单提一下,下面在详细说。

    主要API

    UIKit主要API散落在UIView+UIViewAnimationWithBlocks和UIView+UIViewKeyframeAnimations两个分类

    @interface UIView(UIViewAnimationWithBlocks)
    
    + (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion 
    
    + (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion 
    
    + (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations
    
    + (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay usingSpringWithDamping:(CGFloat)dampingRatio initialSpringVelocity:(CGFloat)velocity options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion 
    
    + (void)transitionWithView:(UIView *)view duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion
    
    + (void)transitionFromView:(UIView *)fromView toView:(UIView *)toView duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options completion:(void (^)(BOOL finished))completion
    
    + (void)performSystemAnimation:(UISystemAnimation)animation onViews:(NSArray *)views options:(UIViewAnimationOptions)options animations:(void (^)(void))parallelAnimations completion:(void (^)(BOOL finished))completion 
    
    @end
    
    @interface UIView (UIViewKeyframeAnimations)
    
    + (void)animateKeyframesWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewKeyframeAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion
    + (void)addKeyframeWithRelativeStartTime:(double)frameStartTime relativeDuration:(double)frameDuration animations:(void (^)(void))animations NS_AVAILABLE_IOS(7_0);
    
    @end

    我们每个API挨着看一下

    + (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion 

    这个是动画的一个常用API,用于创建常用的动画,参数列表如下

    参数 说明
    duration 持续时间
    delay 延时时间开始
    options 动画选项(下面详细解释)
    animations 动画block
    completion 动画结束后的回调

    下面我们看一个动画例子:

        [UIView animateWithDuration:0.5 delay:1.0 options:UIViewAnimationOptionAutoreverse animations:^{
            CGRect frame = testView.frame;
            frame.origin.y += 100;
            testView.frame = frame;
        } completion:^(BOOL finished) {
            btn.hidden = YES;
        }];

    这是在按钮click事件里面的一段代码,btn就是该按钮,testView定义如下

        testView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
        testView.backgroundColor = [UIColor blackColor];
        [self.view addSubview:testView];

    大家运行代码会发现,1秒后动画开始,运行了0.5秒,视图先向下再向上运动100回到原点,然后突然跳到100的位置按钮消失。

    回到原点的原因是我们options写了UIViewAnimationOptionAutoreverse动画选项,该项会在东环正向运行后自动翻转动画运行一遍。

    大家应该能开出来options可以设置动画的一些行为

    options大体上可以分为三类,分为动画属性,动画线性关系,和动画转场效果。

    动画属性:

    UIViewAnimationOptionLayoutSubviews 在AutoLayout下,如果修改AutoLayout,那么子视图也会跟着一起变化
    UIViewAnimationOptionAllowUserInteraction 在动画时,允许用户交互,比如按钮在运动者还可以点击
    UIViewAnimationOptionBeginFromCurrentState 从当前状态开始动画
    UIViewAnimationOptionRepeat 重复动画
    UIViewAnimationOptionAutoreverse 动画执行完毕自动翻转
    UIViewAnimationOptionOverrideInheritedDuration 忽略外层动画嵌套的执行时间
    UIViewAnimationOptionOverrideInheritedCurve 忽略外层动画线性关系

    动画线性关系

    UIViewAnimationOptionShowHideTransitionViews 用显隐的方式替代添加移除图层的动画效果
    UIViewAnimationOptionOverrideInheritedOptions 忽略嵌套继承的选项
    UIViewAnimationOptionCurveEaseInOut 时间曲线函数,由慢到快
    UIViewAnimationOptionCurveEaseIn 时间曲线函数,由慢到特别快
    UIViewAnimationOptionCurveEaseOut 时间曲线函数,由快到慢
    UIViewAnimationOptionCurveLinear 时间曲线函数,匀速

    动画转场效果

    UIViewAnimationOptionTransitionNone 无转场动画
    UIViewAnimationOptionTransitionFlipFromLeft 转场从左翻转
    UIViewAnimationOptionTransitionFlipFromRight 转场从右翻转
    UIViewAnimationOptionTransitionCurlUp 上卷转场
    UIViewAnimationOptionTransitionCurlDown 下卷转场
    UIViewAnimationOptionTransitionCrossDissolve 转场交叉消失
    UIViewAnimationOptionTransitionFlipFromTop 转场从上翻转
    UIViewAnimationOptionTransitionFlipFromBottom 转场从下翻转

    转场动画

    转场动画的API如下,是为了控制视图的跳转而使用的

    [UIView transitionWithView:subView duration:1.0 options:UIViewAnimationOptionTransitionFlipFromLeft animations:^{
            [subView addSubview:testView];
    } completion:^(BOOL finished) {
            
    }];

    运行这段代码可以看到视图被翻转过来的时候添加了testView在上面。

    [UIView transitionFromView:subView toView:testView duration:1.0 options:UIViewAnimationOptionTransitionFlipFromLeft completion:nil];

    这个方法可以控制一个控制器中的视图切换。

    关键帧动画:

    [UIView animateKeyframesWithDuration:2 delay:0 options:UIViewKeyframeAnimationOptionCalculationModeLinear animations:^{
            [UIView addKeyframeWithRelativeStartTime:0 relativeDuration:0.25 animations:^{
                CGRect frame = testView.frame;
                frame.origin.y += 100 * flag;
                testView.frame = frame;
            }];
            [UIView addKeyframeWithRelativeStartTime:0.25 relativeDuration:0.25 animations:^{
                CGRect frame = testView.frame;
                frame.origin.y -= 100 * flag;
                testView.frame = frame;
            }];
            [UIView addKeyframeWithRelativeStartTime:0.5 relativeDuration:0.5 animations:^{
                CGRect frame = testView.frame;
                frame.origin.y += 200 * flag;
                testView.frame = frame;
            }];
        } completion:^(BOOL finished) {
            btn.hidden = YES;
        }];

    可以看到,关键帧动画我们很方便的可以控制动画的整个过程,addKeyframeWithRelativeStartTime:是添加关键帧方法,参数startTime是一个在0~1之间的数字,表示开始时间占总时间的%多少,比如上例中的第一帧就是0,第二针就是25%也就是在0.5秒开始。relativeDuration和开始时间一样,是运行时间占整个时间的百分比。

    弹簧动画

        [UIView animateWithDuration:0.5 delay:1.0 usingSpringWithDamping:1 initialSpringVelocity:0.1 options:UIViewAnimationOptionAutoreverse animations:^{
            CGRect frame = testView.frame;
            frame.origin.y += 100 * flag;
            testView.frame = frame;
        } completion:^(BOOL finished) {
            btn.hidden = YES;
        }];

    弹簧动画的阻尼值,也就是相当于摩擦力的大小,该属性的值从0.0到1.0之间,越靠近0,阻尼越小,弹动的幅度越大,反之阻尼越大,弹动的幅度越小,如果大道一定程度,会出现弹不动的情况。

    弹簧动画的速率,或者说是动力。值越小弹簧的动力越小,弹簧拉伸的幅度越小,反之动力越大,弹簧拉伸的幅度越大。这里需要注意的是,如果设置为0,表示忽略该属性,由动画持续时间和阻尼计算动画的效果。

  • 相关阅读:
    LOJ#6501. 「雅礼集训 2018 Day4」Cube 题解
    LOJ#6510. 「雅礼集训 2018 Day8」A 题解
    LOJ#6513. 「雅礼集训 2018 Day10」足球大战 题解
    LOJ#6507. 「雅礼集训 2018 Day7」A 题解
    LOJ#6038. 「雅礼集训 2017 Day5」远行 题解
    Luogu P4208 [JSOI2008]最小生成树计数
    CodeForces 916D Jamie and To-do List
    CodeForces 573B Bear and Blocks
    CodeForces 460C Present
    CodeForces 786B Legacy
  • 原文地址:https://www.cnblogs.com/madpanda/p/4741373.html
Copyright © 2020-2023  润新知