zoukankan      html  css  js  c++  java
  • 156 UIImageView 和 CADisplayLink 实现 Tom 汤姆猫动画效果的区别(扩展知识:分组(黄色文件夹)和文件夹引用(蓝色文件夹)区别)

    (1)UIImageView 的动画操作,来自定义循环播放动画(不建议使用,内存消耗大)

    (2)CADisplayLink 是一个计时器,但是同 NSTimer 不同的是,CADisplayLink 的刷新周期同屏幕完全一致。

    例如在 iOS 中屏幕刷新周期是60次/秒,CADisplayLink 刷新周期同屏幕刷新一致也是60次/秒,这样一来使用它完成的逐帧动画(又称为“时钟动画”)完全感觉不到动画的停滞情况。

    关键操作:

    效果如下:

    ViewController.h

    1 #import <UIKit/UIKit.h>
    2 
    3 @interface ViewController : UIViewController
    4 @property (strong, nonatomic) UIImageView *imgVAnimation;
    5 @property (strong, nonatomic) CADisplayLink *displayLink;
    6 
    7 @end

    ViewController.m

      1 #import "ViewController.h"
      2 
      3 @interface ViewController ()
      4 - (void)layoutUI;
      5 - (void)changeImage;
      6 - (void)layoutUINoSuggest;
      7 - (NSArray *)imagesFromGroups;
      8 - (NSArray *)imagesFromFolderReferences;
      9 @end
     10 
     11 @implementation ViewController
     12 #define kImgCount 29
     13 
     14 - (void)viewDidLoad {
     15     [super viewDidLoad];
     16     
     17     //[self layoutUINoSuggest];
     18     
     19     [self layoutUI];
     20 }
     21 
     22 - (void)viewWillAppear:(BOOL)animated {
     23     [super viewWillAppear:animated];
     24     
     25     //开始动画;对应使用[self layoutUINoSuggest]的情况
     26     //[_imgVAnimation startAnimating];
     27     
     28     //实例化时钟对象
     29     _displayLink=[CADisplayLink displayLinkWithTarget:self selector:@selector(changeImage)];
     30     //添加时钟对象实例到主运行循环
     31     [_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
     32 }
     33 
     34 - (void)viewWillDisappear:(BOOL)animated {
     35     [super viewWillDisappear:animated];
     36     
     37     //停止动画;对应使用[self layoutUINoSuggest]的情况
     38     //[_imgVAnimation stopAnimating];
     39     
     40     //从主运行循环移除时钟对象实例
     41     [_displayLink removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
     42 }
     43 
     44 - (void)didReceiveMemoryWarning {
     45     [super didReceiveMemoryWarning];
     46     // Dispose of any resources that can be recreated.
     47 }
     48 
     49 #pragma mark - 推荐使用的方式
     50 /**
     51  *  使用CADisplayLink,来自定义循环播放动画(推荐使用,内存消耗小)
     52  *  CADisplayLink是一个计时器,但是同NSTimer不同的是,CADisplayLink的刷新周期同屏幕完全一致。例如在iOS中屏幕刷新周期是60次/秒,CADisplayLink刷新周期同屏幕刷新一致也是60次/秒,这样一来使用它完成的逐帧动画(又称为“时钟动画”)完全感觉不到动画的停滞情况
     53  */
     54 - (void)layoutUI {
     55     _imgVAnimation = [[UIImageView alloc] initWithFrame:self.view.bounds];
     56     [self.view addSubview:_imgVAnimation];
     57 }
     58 
     59 - (void)changeImage {
     60     //定义一个变量记录执行次数
     61     static NSUInteger s=0;
     62     static NSUInteger indexOfImg = 0;
     63     //每秒执行12次if内的语句;分别当s=5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60...
     64     s++;
     65     if (s % 5 == 0) {
     66         UIImage *image=[self imagesFromGroups][indexOfImg];
     67         _imgVAnimation.layer.contents=(id)image.CGImage; //更新图片
     68         
     69         indexOfImg++;
     70         if (indexOfImg == kImgCount) {
     71             indexOfImg = 0;
     72         }
     73     }
     74 }
     75 
     76 #pragma mark - 不建议使用的方式
     77 /**
     78  *  使用图片视图的动画操作,来自定义循环播放动画(不建议使用,内存消耗大)
     79  */
     80 - (void)layoutUINoSuggest {
     81     _imgVAnimation = [[UIImageView alloc] initWithFrame:self.view.bounds];
     82     _imgVAnimation.animationImages = [self imagesFromGroups]; //引用图片数组,导致一次性加载图片数组,内存消耗大
     83     //设置动画持续时间(图片播放周期时间,而不是播放一张图片的时间);单位为秒;默认值为每秒30帧(每秒播放30张图片)
     84     _imgVAnimation.animationDuration = 3;
     85     //设置动画播放重复次数;默认值为0,表示无限循环
     86     _imgVAnimation.animationRepeatCount = 0;
     87     [self.view addSubview:_imgVAnimation];
     88 }
     89 
     90 #pragma mark - 读取图片文件数组操作
     91 /**
     92  *  获取来自分组(黄色文件夹)的图片数组;图片文件路径不需要包含文件夹
     93  *  使用右键“Add Files to...”->“Added folders” : “Create groups”,生成分组(黄色文件夹)
     94  *
     95  *  @return 来自分组(黄色文件夹)的图片数组
     96  */
     97 - (NSArray *)imagesFromGroups {
     98     NSMutableArray *mArrImgForAnimation = [[NSMutableArray alloc] initWithCapacity:kImgCount];
     99     NSString *strImgName;
    100     for (NSUInteger i=0; i<kImgCount; i++) {
    101         strImgName = [NSString stringWithFormat:(i<10 ? @"Happy000%lu" : @"Happy00%lu")
    102                       , (unsigned long)i];
    103         //[mArrImgForAnimation addObject:[UIImage imageNamed:strImgName]]; //[UIImage imageNamed:strImgName]会缓存图片,这里图片多,占内存过大,不建议用
    104         
    105         //读取方式一(推荐使用):
    106         NSString *path = [[NSBundle mainBundle] pathForResource:strImgName ofType:@"jpg"];
    107         //NSString *path = [[NSBundle mainBundle] pathForResource:strImgName ofType:nil]; //这种方式的话,strImgName的格式就为“xx.jpg”
    108         
    109         //读取方式二:
    110         //NSString *path = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:strImgName];
    111         
    112         //为数组mArrImgForAnimation添加数组元素
    113         [mArrImgForAnimation addObject:[UIImage imageWithContentsOfFile:path]]; //虽然没缓存图片,但也可能存在内存泄露问题
    114     }
    115     return mArrImgForAnimation;
    116 }
    117 
    118 /**
    119  *  获取来自文件夹引用(蓝色文件夹)的图片数组;图片文件路径需要包含文件夹
    120  *  使用右键“Add Files to...”->“Added folders” : “Create folder references”,生成文件夹引用(蓝色文件夹)
    121  *
    122  *  @return 来自文件夹引用(蓝色文件夹)的图片数组
    123  */
    124 - (NSArray *)imagesFromFolderReferences {
    125     NSMutableArray *mArrImgForAnimation = [[NSMutableArray alloc] initWithCapacity:kImgCount];
    126     NSString *strImgName;
    127     for (NSUInteger i=0; i<kImgCount; i++) {
    128         strImgName = [NSString stringWithFormat:(i<10 ? @"Happy000%lu" : @"Happy00%lu")
    129                       , (unsigned long)i];
    130         
    131         //读取方式一(推荐使用):
    132         NSString *path = [[NSBundle mainBundle] pathForResource:strImgName ofType:@"jpg" inDirectory:@"TomCat"];
    133         //NSString *path = [[NSBundle mainBundle] pathForResource:strImgName ofType:nil inDirectory:@"TomCat"]; //这种方式的话,strImgName的格式就为“xx.jpg”
    134         
    135         //读取方式二:
    136         //NSString *bundlePath = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@"TomCat"];
    137         //NSString *path = [bundlePath stringByAppendingPathComponent:strImgName];
    138         
    139         //为数组mArrImgForAnimation添加数组元素
    140         [mArrImgForAnimation addObject:[UIImage imageWithContentsOfFile:path]]; //虽然没缓存图片,但也可能存在内存泄露问题
    141     }
    142     return mArrImgForAnimation;
    143 }
    144 
    145 @end
  • 相关阅读:
    c语言之排序
    c语言中的break 和 continue语句
    c语言之循环
    c语言之选择
    使用函数封装代码
    C语言的运算符
    判断两个对象是否相等:hashcode
    更新线上的资源存在删除和添加的情况-要避免空窗期的实现方法
    变量只能设置一次方法
    JAVA-获取系统信息:内存和系统、PID、内核
  • 原文地址:https://www.cnblogs.com/huangjianwu/p/4581536.html
Copyright © 2011-2022 走看看