iOS--Animation总结

来源:互联网 发布:数组对象方法排序 编辑:程序博客网 时间:2024/06/06 18:22

iOS--Animation总结

UIKit框架中

1.UIImageView里的序列帧动画

  • 将序列帧动画图片存入imageView.animationImages数组中

示例:

NSMutableArray * array = [NSMutableArray array];for (int i = 1; i < 6; i++) {    //将图片存入数组    NSString * string = [NSString stringWithFormat:@"hehua0%d",i];    UIImage * image = [UIImage imageNamed:string];    [array addObject:image];}self.imageView = [[UIImageView alloc] initWithFrame:CGRectMake(100, 100, 200, 200)];//设置动画图片self.imageView.animationImages = array;//动画时间self.imageView.animationDuration = 1;//动画播放重复次数,值为0时,无限循环self.imageView.animationRepeatCount = 0;//开始动画[self.imageView startAnimating];//结束动画[self.imageView stopAnimating];
  • 播放GIF动画

可为UIImageView添加类别来实现方法

如+ (UIImageView )imageViewWithGIFFile:(NSString )file frame:(CGRect)frame;

导入头文件和

   /**   * ARC下需要手动管理内存的有(Core)   *CT开头,例如:CTRunRef   *CF开头,例如:CTFrameRef   *CG开头,例如:CGImageSourceRef   */  @implementation UIImageView (GIF)  + (UIImageView *)imageViewWithGIFFile:(NSString *)file frame:(CGRect)frame  {    UIImageView *imageView = [[UIImageView alloc] initWithFrame:frame];    // 加载gif文件数据    NSData *gifData = [NSData dataWithContentsOfFile:file];        // GIF动画图片数组    NSMutableArray *frames = nil;    // 图像源引用    CGImageSourceRef src = CGImageSourceCreateWithData((__bridge CFDataRef)gifData, NULL);    // 动画时长    CGFloat animationTime = 0.f;        if (src) {        // 获取gif图片的帧数        size_t count = CGImageSourceGetCount(src);        // 实例化图片数组        frames = [NSMutableArray arrayWithCapacity:count];                for (size_t i = 0; i < count; i++) {            // 获取指定帧图像            CGImageRef image = CGImageSourceCreateImageAtIndex(src, i, NULL);                        // 获取GIF动画时长            NSDictionary *properties = (__bridge NSDictionary *)CGImageSourceCopyPropertiesAtIndex(src, i, NULL);            NSDictionary *frameProperties = [properties objectForKey:(NSString *)kCGImagePropertyGIFDictionary];            NSNumber *delayTime = [frameProperties objectForKey:(NSString *)kCGImagePropertyGIFUnclampedDelayTime];            animationTime += [delayTime floatValue];                        if (image) {                [frames addObject:[UIImage imageWithCGImage:image]];                CGImageRelease(image);            }        }                CFRelease(src);    }        [imageView setImage:[frames objectAtIndex:0]];    [imageView setBackgroundColor:[UIColor clearColor]];    [imageView setAnimationImages:frames];    [imageView setAnimationDuration:animationTime];    [imageView startAnimating];        return imageView;  }

2.UIView动画

  • 简单动画

    //开始动画    [UIView beginAnimations:@"自定义动画名称" context:nil];    //延迟2秒执行    //[UIView setAnimationDelay:2];    //设置动画时间    [UIView setAnimationDuration:1];    //设置动画代理    [UIView setAnimationDelegate:self];    //将要开始动画    [UIView setAnimationWillStartSelector:@selector(要开始动画时执行)];    //已经结束动画    [UIView setAnimationDidStopSelector:@selector(结束动画执行)];    //设置动画的速度变化    [UIView setAnimationCurve:UIViewAnimationCurveEaseIn];    //设置重复次数    //[UIView setAnimationRepeatCount:3];    //动画的反转    //[UIView setAnimationRepeatAutoreverses:YES];        //设置UIView的位置变化,大小变化,透明度        //    self.imageView.alpha = 0;    //    self.testView.backgroundColor = [UIColor redColor];    //    //    distantce += 20;    //    //    self.testView.frame = CGRectMake(distantce, 0, 100, 100);        //拉伸    // self.testView.transform = CGAffineTransformMakeScale(1.5, 1.5);    //平移    //    self.testView.transform = CGAffineTransformMakeTranslation(100, 100);    //    self.testView.transform = CGAffineTransformTranslate(self.testView.transform, 20, 0);        //旋转    //self.testView.transform = CGAffineTransformMakeRotation(M_PI_2);    //self.testView.transform = CGAffineTransformRotate(self.testView.transform, M_PI_4/2);        //提交动画    [UIView commitAnimations];
  • 转场动画

(1)在一个UIView上添加两个imageView,然后设置动画

 [UIView beginAnimations:@"transition" context:nil]; [UIView setAnimationDuration:2];      //设置转场动画  [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.contentView cache:YES];     [self.contentView exchangeSubviewAtIndex:0 withSubviewAtIndex:1];     [UIView commitAnimations];    

(2)UIView block转场动画

secondView -> firstView

这个方法会作用于fromView的父视图,用于切换两个view,通过执行这个方法,会将formView从其父视图上移除,将toView重新粘在其父视图上,展现一个动画效果。

[UIView transitionFromView:self.secondView toView:self.firstView duration:2 options:UIViewAnimationOptionTransitionCurlUp completion:^(BOOL finished) {         }];    

转场动画的block实现

 [UIView transitionWithView:self.contentView duration:2 options:UIViewAnimationOptionTransitionFlipFromLeft animations:^{    //1.该方法可以实现两个页面的来回切换    [self.contentView exchangeSubviewAtIndex:0 withSubviewAtIndex:1];        //2.该方法只能实现一次转场动画//  [self.firstView removeFromSuperview];//  [self.contentView addSubview:self.secondView];                    } completion:^(BOOL finished) {            }];
  • UIView的block动画

(1)简单block动画的实现

1 图片的透明度变化动画     //Duration动画时间 animations里是要到达的状态,completion里是动画完成之后的代码块     [UIView animateWithDuration:1 animations:^{      self.imageView.alpha = 0;    } completion:^(BOOL finished) {                    [UIView animateWithDuration:1 animations:^{                        self.imageView.alpha = 1;        } completion:^(BOOL finished) {                   }];  }];
2 图片的旋转变化动画[UIView animateWithDuration:1 animations:^{                self.imageView.transform = CGAffineTransformRotate(self.imageView.transform, M_PI_2);            } completion:^(BOOL finished) {                [UIView animateWithDuration:1 animations:^{            //下面是实现图片旋转一定度数后返回原位置的两种方法            self.imageView.transform = CGAffineTransformRotate(self.imageView.transform, -M_PI_2);                        //CGAffineTransformIdentity恢复最初状态//            self.imageView.transform = CGAffineTransformIdentity;        }];            }];
3 增加了动画延迟    [UIView animateWithDuration:1 delay:2 options:UIViewAnimationOptionCurveEaseOut animations:^{        self.imageView.backgroundColor = [UIColor grayColor];    } completion:^(BOOL finished) {            }];

(2) 带弹性效果的动画

    //Damping 弹力 0 ~ 1      //SpringVelocity 弹簧初速度       [UIView animateWithDuration:1 delay:0 usingSpringWithDamping:0.5 initialSpringVelocity:10 options:UIViewAnimationOptionCurveLinear animations:^{        self.imageView.frame = CGRectMake(200, 100, 100, 100);            } completion:^(BOOL finished) {            }];

(3)关键帧动画

    [UIView animateKeyframesWithDuration:3.0 delay:0 options:UIViewKeyframeAnimationOptionCalculationModeLinear animations:^{                [UIView addKeyframeWithRelativeStartTime:0 relativeDuration:1/6.0 animations:^{            self.imageView.backgroundColor = [UIColor redColor];        }];                [UIView addKeyframeWithRelativeStartTime:1/6.0 relativeDuration:3/6.0 animations:^{            self.imageView.backgroundColor = [UIColor blueColor];        }];                [UIView addKeyframeWithRelativeStartTime:4/6.0 relativeDuration:2/6.0 animations:^{            self.imageView.backgroundColor = [UIColor orangeColor];        }];                    } completion:^(BOOL finished) {            }];

QuartzCore框架中

3.CALayer的隐式动画

  • 什么时候使用CALayer,什么时候使用UIView?

当视图需要响应时使用UIView,仅作为展示使用CALayer.

隐式动画只存在于CALayer的子层上

    CALayer * layer = [CALayer layer];        layer.backgroundColor = [UIColor greenColor].CGColor;        layer.frame = CGRectMake(100, 100, 100, 100);    [self.view.layer addSublayer:layer];    //当执行layer变化语句时,默认有动画,即隐式动画    _layer.frame = CGRectMake(100, 100, arc4random_uniform(100), arc4random_uniform(100));

4.核心动画Core Animation

?核心动画和UIView动画的区别

 核心动画一切都是假象,并不会真实的改变图层的属性值,如果以后做动画的时候,不需要与用户交互,通常用核心动画(转场) UIView动画必须通过修改属性的真实值,才有动画效果

CAAnimation是一个抽象类,mac,iOS 通用,遵循了CAMediaTiming协议和CAAction协议!我们不要直接使用CAAnimation类,而是使用其子类:

具体可看 http://www.henishuo.com/caanimation-indtroduce-in-detail/

  • CATransition:提供渐变效果,如推拉push效果,消退fade效果,揭开reveal效果
  • CAAnimationGroup:允许多个动画同时播放
  • CABasicAnimation: 提供了对单一动画的实现
  • CAKeyframeAnimation: 关键桢动画,可以定义动画路线
  • CAPropertyAnimation:属性动画,通常不直接使用,而是使用CABasicAnimation子类

  • 动画路径:完整路径对照表:https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/CoreAnimation_guide/Key-ValueCodingExtensions/Key-ValueCodingExtensions.html

CAAnimation(父类) -> CAPropertyAnimation 属性动画 -> (CABasicAnimation 基础动画 ,CAKeyframeAnimation 关键帧动画)

CAAnimation -> CAAnimationGroup 动画组

  • CABasicAnimation基础动画

    //创建基础动画    CABasicAnimation * basic = [CABasicAnimation animation];    //动画路径    basic.keyPath = @"position";        //绝对距离    //设置初始状态//    basic.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, 0)];    //终止状态//    basic.toValue = [NSValue valueWithCGPoint:CGPointMake(300, 300)];        //动画距离(相对距离)    //basic.byValue = [NSValue valueWithCGPoint:CGPointMake(200, 200)];        //动画的初始和结束的模式 fillMode和removedOnCompletion要配合使用    basic.fillMode = kCAFillModeForwards;// @"forwards";    //动画完成在layer中删除    basic.removedOnCompletion = NO;        //如果初始状态就是当前动画未执行的位置        //动画时间    basic.duration = 1;        //动画的速度变化 eg:kCAMediaTimingFunctionEaseIn越来越快    basic.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];    //?    //animation.timingFunction = [CAMediaTimingFunction functionWithControlPoints:0.5 :0 :0.9 :0.7];        //添加动画    [_animationView.layer addAnimation:basic forKey:@"basic"];
  • CAKeyframeAnimation 关键帧动画

    //创建关键帧动画    CAKeyframeAnimation * keyframe = [CAKeyframeAnimation animation];        keyframe.keyPath = @"position.x";        //设置关键帧的位置    keyframe.values = @[@0,@10,@-10,@10,@0];    //设置关键帧的时间    keyframe.keyTimes = @[ @0, @(1 / 6.0), @(3 / 6.0), @(5 / 6.0), @1 ];        //无需设置起始位置    keyframe.additive = YES;        //calculationMode设置加速度,kCAAnimationPaced保持恒定的加速度,如果设置calculationMode,keyTimes失效    keyframe.calculationMode = kCAAnimationPaced;        //设置时间    keyframe.duration = 0.5;        [_animationView.layer addAnimation:keyframe forKey:@"keyframe"];
利用贝塞尔    UIView * v = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 30, 30)];    v.backgroundColor = [UIColor grayColor];    [self.view addSubview:v];    UIBezierPath * path = [UIBezierPath bezierPathWithRect:CGRectMake(50, 50, 300, 300)];        //创建关键帧动画    CAKeyframeAnimation * keyframe = [CAKeyframeAnimation animation];        keyframe.keyPath = @"position";        keyframe.path = path.CGPath;        //设置时间    keyframe.duration = 2;        //重复次数    keyframe.repeatCount = HUGE_VALF; //MAXFLOAT;        [_animationView.layer addAnimation:keyframe forKey:@"keyframe"];
  • CAAnimationGroup动画组

    CABasicAnimation * basic1 = [CABasicAnimation animation];    basic1.keyPath = @"transform.scale";    basic1.toValue = @(arc4random_uniform(5));    basic1.duration = 0.5;    basic1.removedOnCompletion = NO;    basic1.fillMode = @"forwards";//    [self.animationView.layer addAnimation:basic1 forKey:@"aaa"];        CABasicAnimation * basic2 = [CABasicAnimation animation];    basic2.keyPath = @"transform.rotation";    basic2.toValue = @(arc4random_uniform(M_PI));    basic2.duration = 0.5;    basic2.beginTime = 0.5;    //    [self.animationView.layer addAnimation:basic2 forKey:nil];    CAAnimationGroup * group = [CAAnimationGroup animation];        group.duration = 1;    group.removedOnCompletion = NO;    group.fillMode = @"forwards";    group.animations = @[basic1,basic2];        [self.animationView.layer addAnimation:group forKey:nil];
  • CATransition过渡动画

设置视图变化时的动画效果

  • 1.#define定义的常量

  • kCATransitionFade 交叉淡化过渡

  • kCATransitionMoveIn 新视图移到旧视图上面

  • kCATransitionPush 新视图把旧视图推出去

  • kCATransitionReveal 将旧视图移开,显示下面的新视图

  • 2.用字符串表示

  • pageCurl 向上翻一页

  • pageUnCurl 向下翻一页

  • rippleEffect 滴水效果

  • suckEffect 收缩效果,如一块布被抽走

  • cube 立方体效果

  • oglFlip 上下翻转效果

    CATransition * transition = [CATransition animation];    transition.type = @"suckEffect";    transition.subtype = @"fromLeft";    transition.duration = 2;    [self.imageView.layer addAnimation:transition forKey:nil];

//CADisplayLink,selector每秒钟默认调用60次。

//CADisplayLink和NSTimer区别:CADisplayLink用来做绘图,重绘。NSTimer用于计时,重复调用。

````
//创建CADisplayLink
self.displaylink = [CADisplayLink displayLinkWithTarget:self selector:@selector(handleAction:)];

//调用次数 = 60 / frameInterval

// self.displaylink.frameInterval = 3;

//将CADisplayLink放入RunLoop里[self.displaylink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];

````

Facebook POP动画

  • poping开源库

POP比较好的一点是保留了动画结束后的状态,通过block回调。使用POPAnimatableProperty 可以快速添加基本动画,也可以自定义属性动画。

---弹性动画---- (void)spring{    POPSpringAnimation* framePOP = [POPSpringAnimation animationWithPropertyNamed:kPOPViewBackgroundColor];    framePOP.springSpeed = 10.f;    framePOP.springBounciness = 4.f;    framePOP.toValue = [UIColor greenColor];    [framePOP setCompletionBlock:^(POPAnimation * anim , BOOL finsih) {        if (finsih) {            NSLog(@"view.frame = %@",NSStringFromCGRect(view.frame));        }    }];    [view pop_addAnimation:framePOP forKey:@"go"];}
---减缓动画——--- (void)Decay{    POPDecayAnimation* decay = [POPDecayAnimation animationWithPropertyNamed:kPOPViewFrame];// decay.toValue = [NSValue valueWithCGRect:CGRectMake(200, 400, 100, 100)];    decay.velocity = [NSValue valueWithCGRect:CGRectMake(200, 300, 100, 100)];    [view pop_addAnimation:decay forKey:@"go"];}
---基本动画----(void)basic{    POPBasicAnimation* basicAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerCornerRadius];    basicAnimation.toValue = [NSNumber numberWithFloat:CGRectGetHeight(view.frame)/2.];    basicAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];// basicAnimation.duration = 3.f;    [basicAnimation setCompletionBlock:^(POPAnimation * ani, BOOL fin) {        if (fin) {            NSLog(@"view.frame = %@",NSStringFromCGRect(view.frame));// POPBasicAnimation* newBasic = [POPBasicAnimation easeInEaseOutAnimation];// newBasic.property = [POPAnimatableProperty propertyWithName:kPOPLayerCornerRadius];// newBasic.toValue = [NSNumber numberWithFloat:0];// [view.layer pop_addAnimation:newBasic forKey:@"go"];        }    }];    [view.layer pop_addAnimation:basicAnimation forKey:@"frameChange"];
---组合动画----(void)group{    view.transform = CGAffineTransformMakeRotation(M_PI_2/3);    POPBasicAnimation* spring = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerPositionY];    spring.beginTime = CACurrentMediaTime();    spring.duration = .4f;    spring.fromValue = [NSNumber numberWithFloat:-100.f];    spring.toValue = [NSNumber numberWithFloat:CGRectGetMinY(view.frame) + 80];    [spring setCompletionBlock:^(POPAnimation * ani, BOOL fin) {    }];    POPBasicAnimation* basic = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerRotation];    basic.beginTime = CACurrentMediaTime();    basic.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];    basic.toValue = [NSNumber numberWithFloat:-M_PI_4];    basic.duration = .4f;    POPBasicAnimation* rotation = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerRotation];    rotation.beginTime = CACurrentMediaTime() + .4f;    rotation.toValue = [NSNumber numberWithFloat:0.f];    rotation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];    rotation.duration = .25f;    POPBasicAnimation* donw = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerPositionY];    donw.beginTime = CACurrentMediaTime() + 0.4f;    donw.toValue = [NSNumber numberWithFloat:CGRectGetMinY(view.frame)];    donw.duration = .25f;    donw.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];    [view.layer pop_addAnimation:spring forKey:@"spring"];    [view.layer pop_addAnimation:basic forKey:@"basic"];    [view.layer pop_addAnimation:donw forKey:@"down"];    [view.layer pop_addAnimation:rotation forKey:@"rotation"];}
0 0
原创粉丝点击