[iOS]UIView动画总结

UIView类本身自带了一套动画,当UIView的某个属性发生改变时,UIView会自动为其加上动画效果,当然,是否需要动画,以及怎样动画,需要我们告诉UIView;

首先了解一下,UIView的哪些属性可以用来做动画?

常用的有,坐标:frame,bounds,center;透明度:alpha;旋转:transform,颜色:backgroundColor,textColor

UIView动画,常用方法有:

@interface UIView(UIViewAnimation)

//开始动画
+ (void)beginAnimations:(nullable NSString *)animationID context:(nullable void *)context;
//提交动画
+(void)commitAnimations;

//设置代理
+ (void)setAnimationDelegate:(nullable id)delegate;
// default = nil 设置动画将要开始时执行的方法
// default = NULL. -animationWillStart:(NSString *)animationID context:(void *)context
+ (void)setAnimationWillStartSelector:(nullable SEL)selector;

//动画停止时的执行的方法
+ (void)setAnimationDidStopSelector:(nullable SEL)selector; // default = NULL. -animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context
//设置动画时间  default = 0.2
+ (void)setAnimationDuration:(NSTimeInterval)duration;
//延迟时间  default = 0.0
+ (void)setAnimationDelay:(NSTimeInterval)delay;

// default = now ([NSDate date])
+ (void)setAnimationStartDate:(NSDate *)startDate;
//设置动画样式 default = UIViewAnimationCurveEaseInOut
+ (void)setAnimationCurve:(UIViewAnimationCurve)curve;
// default = 0.0.  May be fractional 设置动画重复次数
+ (void)setAnimationRepeatCount:(float)repeatCount;
// default = NO. used if repeat count is non-zero 是否自动逆向动画
+ (void)setAnimationRepeatAutoreverses:(BOOL)repeatAutoreverses;
@end

UIView动画快,一般是以beginAnimation开始,以commitAnimations结束,其他的设置在这之间.

一,平移

平移只需给定最终的坐标,动画就会执行

例如,实现这么一个动画:将view从一个位置,缓慢移动到另一个位置;可以这样实现:

    //开始
    [UIView beginAnimations:nil context:nil];
    //设置动画时间
    [UIView setAnimationDuration:2.0];
    //设置结束的位置
    label.frame = CGRectMake(0, 300, 100, 40);
    //提交动画
    [UIView commitAnimations];
就这样就实现了一个简单的平移动画!

下面实现一个在两点之间来回移动的动画,只需在上面的代码中加上两句:

//开始
    [UIView beginAnimations:nil context:nil];
    //设置动画时间
    [UIView setAnimationDuration:2.0];
    
    //note:设置动画重复的两句代码一定要在动画结束位置代码的前边
    //设置动画是否重复来回
    [UIView setAnimationRepeatAutoreverses:YES];
    //设置动画重复次数,0和1都是一次,
    //LONG_MAX就是无限大
    [UIView setAnimationRepeatCount:LONG_MAX];
    
    //设置结束的位置
    label.frame = CGRectMake(0, 300, 100, 40);
    //提交动画
    [UIView commitAnimations];

需要注意的是,新加的两句代码一定要写在设置结束位置的代码的前面,否则不会有效果!

二,旋转

旋转主要是用了view的transform属性

[UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:2];
    [UIView setAnimationRepeatCount:LONG_MAX];
    
    //    CGAffineTransformMakeRotation 是一个旋转的方法,后面需要传一个旋转的角度,这个是弧度,系统会把这个弧度转化为相应的矩阵
    
    //    此方法只能旋转一次
    //    逆时针旋转加-号
    CGAffineTransform  trans2 = CGAffineTransformMakeRotation(M_PI);
    
    
    //    让视图连续旋转,第一个参数记录上次旋转的位置,第二个参数是每次旋转的角度
    CGAffineTransform  trans3 = CGAffineTransformRotate(label.transform, M_PI);
    
    //    大小的变换动画,后边传 x 和 y 的变大倍数
    CGAffineTransform trans4 =  CGAffineTransformMakeScale(2, 2);
    
    
    
    label.transform = trans2;
    [UIView commitAnimations];

三,转场

UIView动画也可以加在视图转场时

 FirstViewController *first = [[FirstViewController alloc]init];
    
    UIWindow *win = [[[UIApplication sharedApplication]delegate]window];
    win.rootViewController = first;
    
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:1];
    
    //    Transition  转换 变化
    //    UIViewAnimationTransitionCurlUp      flip 翻转   curl 卷曲
    //    forView:要实现翻转效果的两个视图的父视图
    //    cache   缓存   YES
    [UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:win cache:YES];
    
    [UIView commitAnimations];

四,绑方法

有时候需要在动画结束后,执行某些操作,这时,可以通过绑定动画结束方法实现,需要设置代理

//开始
    [UIView beginAnimations:nil context:nil];
    //设置动画时间
    [UIView setAnimationDuration:2.0];
    
    [UIView setAnimationDidStopSelector:@selector(cc)]; //绑定动画结束的方法
    [UIView setAnimationDelegate:self];
    //设置结束的位置
    label.frame = CGRectMake(0, 300, 100, 40);
    //提交动画
    [UIView commitAnimations];

这样在动画结束后就会去调用cc方法;

你在底层看API的时候发现在setAnimationDidStopSelector的旁边有个注释:

+ (void)setAnimationDidStopSelector:(nullable SEL)selector;                  // default = NULL. -animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context

你会感到这个注释有些奇怪;也不知道是哪路大神发现的,注释后面是一个隐藏的动画执行结束后调用的方法,这样在UIView动画里只需设置好代理,不用设置结束方法,但是要实现注释里的方法,动画在结束后就会自动调用那个方法:

-(void)animation4 {
    
    //开始
    [UIView beginAnimations:nil context:nil];
    //设置动画时间
    [UIView setAnimationDuration:2.0];
    
    [UIView setAnimationDelegate:self];
    //设置结束的位置
    label.frame = CGRectMake(0, 300, 100, 40);
    //提交动画
    [UIView commitAnimations];
}

- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
    NSLog(@"动画结束了");
}

也许你会发现,动画的开始方法beginAnimation中有两个参数, 而系统隐藏的方法里也有两个参数与之相同,两者有什么关系呢?

//第一个参数是动画的标示符,用于区分是哪个动画
//第二个参数是传递到动画结束方法的对象
+ (void)beginAnimations:(nullable NSString *)animationID context:(nullable void *)context

/**
 *  @author LQQ, 16-04-10 15:04:25
 *
 *  动画结束方法
 *
 *  @param animationID 和开始动画的第一个参数匹配,动画的标示符,当动画有多个时,用于标识是哪个动画调用的该方法
 *  @param finished 不和上面的任意一个参数匹配,它标志着这个动画是否做完毕,如果finished = 1,代表完毕  如果finished = 0 ,代表此动画夭折
 *  @param context 和开始动画的第二个参数匹配,动画中传递的参数,从这里接收
 */
- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context

如果一个页面的动画比较多,可以通过animationID来区分动画,执行相应的操作,需要传递的参数可以从context获取,它是void类型,在这里相当于id类型,接收后转换为相应的类型即可!

-(void)animation4 {
    
    //开始
    
    /**
     *  @author LQQ, 16-04-10 15:04:21
     *  第一个参数是动画的标示符,用于区分是哪个动画
        第二个参数是传递到动画结束方法的对象
     *  + (void)beginAnimations:(nullable NSString *)animationID context:(nullable void *)context
     */
    [UIView beginAnimations:@"animation4" context:@"1234"];
    //设置动画时间
    [UIView setAnimationDuration:2.0];
    
    [UIView setAnimationDelegate:self];
    //设置结束的位置
    label.frame = CGRectMake(0, 300, 100, 40);
    //提交动画
    [UIView commitAnimations];
}

/**
 *  @author LQQ, 16-04-10 15:04:25
 *
 *  动画结束方法
 *
 *  @param animationID 和开始动画的第一个参数匹配,动画的标示符,当动画有多个时,用于标识是哪个动画调用的该方法
 *  @param finished 不和上面的任意一个参数匹配,它标志着这个动画是否做完毕,如果finished = 1,代表完毕  如果finished = 0 ,代表此动画夭折
 *  @param context 和开始动画的第二个参数匹配,动画中传递的参数,从这里接收
 */
- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
    if ([animationID isEqualToString:@"animation4"]) {
        
        NSString *str = (__bridge NSString*)context;
        NSLog(@"动画结束了,传递的参数是:%@",str);
    }
}

输出:

[5583:421426] 动画结束了,传递的参数是:1234

在动画中通过setAnimationDidStopSelector设置 的方法,如果不是使用的系统默认的方法,需要传递参数的话,方法的格式和参数类型要和系统那个方法一致,方法名可以自定义!


UIView也提供了一些以block形式添加动画的方法

/**
 *  @author LQQ, 16-04-10 16:04:29
 *
 *
 *
 *  @param duration 动画持续时间
 *  @param delay 延迟执行动画
 *  @param options 动画的控制类型
 *  @param animations 将改变视图属性的代码写在这个block中,例如:最终的坐标
 *  @param completion 动画结束后执行的block
 */
+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^ __nullable)(BOOL finished))completion NS_AVAILABLE_IOS(4_0);

/**
 *  @author LQQ, 16-04-10 16:04:31
 *
 *
 *  @param duration 动画持续时间
 *  @param animations 将改变视图属性的代码写在这个block中,例如:最终的坐标
 *  @param completion 动画结束后执行的block
 */
+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations completion:(void (^ __nullable)(BOOL finished))completion NS_AVAILABLE_IOS(4_0); // delay = 0.0, options = 0

/**
 *  @author LQQ, 16-04-10 16:04:09
 *
 *
 *  @param duration 动画持续时间
 *  @param animations 动画结束后执行的block
 */
+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations NS_AVAILABLE_IOS(4_0); // delay = 0.0, options = 0, completion = NULL

/**
 

 @param duration 动画持续时间
 @param delay 延迟执行
 @param dampingRatio 弹簧震动效果,范围为0-1, 数值越小, 弹簧的震动效果越明显
 @param velocity 出事速度,数值越大, 开始移动速度越快
 @param options 动画的类型, 是个枚举
 @param animations 需要做的动画
 @param completion 动画完成后的回调
 */
+ (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


使用block动画实现平移的动画可以这么写:

[UIView animateWithDuration:2.0 animations:^{
        label.frame = CGRectMake(0, 300, 100, 40);
    }];

来回平移的动画:

[UIView animateWithDuration:2.0 delay:1.0 options:UIViewAnimationOptionRepeat|UIViewAnimationOptionAutoreverse animations:^{
        label.frame = CGRectMake(0, 300, 100, 40);
    } completion:nil];

UIView动画commit之后如何停止?

只需使用做动画的view的layer调用如下方法:

[label.layer removeAllAnimations];

即可停止当前的UIView动画,需要导入框架 #import <QuartzCore/QuartzCore.h>

最后,介绍一种UIImageView的帧动画(类似于GIF的动画):

 //设置一组帧动画图片
    imgview.animationImages = array;
    //设置动画持续时间
    imgview.animationDuration = 1.0;
    //设置动画的重复次数,0代表无限次
    imgview.animationRepeatCount = 0;
    //给图片视图设置一张图片
    imgview.image = [UIImage imageNamed:@"plane1.png"];
    //把图片视图添加到窗口上
    [self.window addSubview:imgview];
    //启动动画
    [imgview startAnimating];

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值