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

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

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

关键操作:

效果如下:

ViewController.h

 #import <UIKit/UIKit.h>

 @interface ViewController : UIViewController
@property (strong, nonatomic) UIImageView *imgVAnimation;
@property (strong, nonatomic) CADisplayLink *displayLink; @end

ViewController.m

 #import "ViewController.h"

 @interface ViewController ()
- (void)layoutUI;
- (void)changeImage;
- (void)layoutUINoSuggest;
- (NSArray *)imagesFromGroups;
- (NSArray *)imagesFromFolderReferences;
@end @implementation ViewController
#define kImgCount 29 - (void)viewDidLoad {
[super viewDidLoad]; //[self layoutUINoSuggest]; [self layoutUI];
} - (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated]; //开始动画;对应使用[self layoutUINoSuggest]的情况
//[_imgVAnimation startAnimating]; //实例化时钟对象
_displayLink=[CADisplayLink displayLinkWithTarget:self selector:@selector(changeImage)];
//添加时钟对象实例到主运行循环
[_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
} - (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated]; //停止动画;对应使用[self layoutUINoSuggest]的情况
//[_imgVAnimation stopAnimating]; //从主运行循环移除时钟对象实例
[_displayLink removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
} - (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
} #pragma mark - 推荐使用的方式
/**
* 使用CADisplayLink,来自定义循环播放动画(推荐使用,内存消耗小)
* CADisplayLink是一个计时器,但是同NSTimer不同的是,CADisplayLink的刷新周期同屏幕完全一致。例如在iOS中屏幕刷新周期是60次/秒,CADisplayLink刷新周期同屏幕刷新一致也是60次/秒,这样一来使用它完成的逐帧动画(又称为“时钟动画”)完全感觉不到动画的停滞情况
*/
- (void)layoutUI {
_imgVAnimation = [[UIImageView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:_imgVAnimation];
} - (void)changeImage {
//定义一个变量记录执行次数
static NSUInteger s=;
static NSUInteger indexOfImg = ;
//每秒执行12次if内的语句;分别当s=5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60...
s++;
if (s % == ) {
UIImage *image=[self imagesFromGroups][indexOfImg];
_imgVAnimation.layer.contents=(id)image.CGImage; //更新图片 indexOfImg++;
if (indexOfImg == kImgCount) {
indexOfImg = ;
}
}
} #pragma mark - 不建议使用的方式
/**
* 使用图片视图的动画操作,来自定义循环播放动画(不建议使用,内存消耗大)
*/
- (void)layoutUINoSuggest {
_imgVAnimation = [[UIImageView alloc] initWithFrame:self.view.bounds];
_imgVAnimation.animationImages = [self imagesFromGroups]; //引用图片数组,导致一次性加载图片数组,内存消耗大
//设置动画持续时间(图片播放周期时间,而不是播放一张图片的时间);单位为秒;默认值为每秒30帧(每秒播放30张图片)
_imgVAnimation.animationDuration = ;
//设置动画播放重复次数;默认值为0,表示无限循环
_imgVAnimation.animationRepeatCount = ;
[self.view addSubview:_imgVAnimation];
} #pragma mark - 读取图片文件数组操作
/**
* 获取来自分组(黄色文件夹)的图片数组;图片文件路径不需要包含文件夹
* 使用右键“Add Files to...”->“Added folders” : “Create groups”,生成分组(黄色文件夹)
*
* @return 来自分组(黄色文件夹)的图片数组
*/
- (NSArray *)imagesFromGroups {
NSMutableArray *mArrImgForAnimation = [[NSMutableArray alloc] initWithCapacity:kImgCount];
NSString *strImgName;
for (NSUInteger i=; i<kImgCount; i++) {
strImgName = [NSString stringWithFormat:(i< ? @"Happy000%lu" : @"Happy00%lu")
, (unsigned long)i];
//[mArrImgForAnimation addObject:[UIImage imageNamed:strImgName]]; //[UIImage imageNamed:strImgName]会缓存图片,这里图片多,占内存过大,不建议用 //读取方式一(推荐使用):
NSString *path = [[NSBundle mainBundle] pathForResource:strImgName ofType:@"jpg"];
//NSString *path = [[NSBundle mainBundle] pathForResource:strImgName ofType:nil]; //这种方式的话,strImgName的格式就为“xx.jpg” //读取方式二:
//NSString *path = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:strImgName]; //为数组mArrImgForAnimation添加数组元素
[mArrImgForAnimation addObject:[UIImage imageWithContentsOfFile:path]]; //虽然没缓存图片,但也可能存在内存泄露问题
}
return mArrImgForAnimation;
} /**
* 获取来自文件夹引用(蓝色文件夹)的图片数组;图片文件路径需要包含文件夹
* 使用右键“Add Files to...”->“Added folders” : “Create folder references”,生成文件夹引用(蓝色文件夹)
*
* @return 来自文件夹引用(蓝色文件夹)的图片数组
*/
- (NSArray *)imagesFromFolderReferences {
NSMutableArray *mArrImgForAnimation = [[NSMutableArray alloc] initWithCapacity:kImgCount];
NSString *strImgName;
for (NSUInteger i=; i<kImgCount; i++) {
strImgName = [NSString stringWithFormat:(i< ? @"Happy000%lu" : @"Happy00%lu")
, (unsigned long)i]; //读取方式一(推荐使用):
NSString *path = [[NSBundle mainBundle] pathForResource:strImgName ofType:@"jpg" inDirectory:@"TomCat"];
//NSString *path = [[NSBundle mainBundle] pathForResource:strImgName ofType:nil inDirectory:@"TomCat"]; //这种方式的话,strImgName的格式就为“xx.jpg” //读取方式二:
//NSString *bundlePath = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@"TomCat"];
//NSString *path = [bundlePath stringByAppendingPathComponent:strImgName]; //为数组mArrImgForAnimation添加数组元素
[mArrImgForAnimation addObject:[UIImage imageWithContentsOfFile:path]]; //虽然没缓存图片,但也可能存在内存泄露问题
}
return mArrImgForAnimation;
} @end

156 UIImageView 和 CADisplayLink 实现 Tom 汤姆猫动画效果的区别(扩展知识:分组(黄色文件夹)和文件夹引用(蓝色文件夹)区别)的更多相关文章

  1. iOS- 利用UIImageView自己整了个不会说话的汤姆猫

    1.实现思路 先说说我实现它的主要思路,很简单,主要利用UIImageView连续动画播放,和按钮的点击事件,就可以完成了这么一个简单的不会说话的汤姆猫. 2.实现细节 2.1.加载本地字典里保存的本 ...

  2. [iOS基础控件 - 3.4] 汤姆猫

    @import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css); @import url(/ ...

  3. [UI基础][不会说话的汤姆猫]

    会说话的汤姆猫这个APP层级风靡一时,其UI部分就是利用了序列动画的技术, 接下来 我们用汤姆猫来演示怎么制作序列动画. [要求]: 1.学会使用序列动画的方法 2.学会分析动画播放中内存占用高的问题 ...

  4. 声音变调算法PitchShift(模拟汤姆猫) 附完整C++算法实现代码

    上周看到一个变调算法,挺有意思的,原本计划尝试用来润色TTS合成效果的. 实测感觉还需要进一步改进,待有空再思考改进方案. 算法细节原文,移步链接: http://blogs.zynaptiq.com ...

  5. iOS_5_汤姆猫

    终于效果图: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcHJlX2VtaW5lbnQ=/font/5a6L5L2T/fontsize/400/fill ...

  6. 使用UISegementControl实现简易汤姆猫程序

    // // TomViewController.m #import "TomViewController.h" #import <AVFoundation/AVFoundat ...

  7. IOS 汤姆猫核心代码

    // // MJViewController.m // 03-Tom // // Created by apple on 13-11-24. // Copyright (c) 2013年 itcast ...

  8. 【Web网站服务器开发】apache和tomcat 阿帕奇和汤姆猫

    经常在用apache和tomcat等这些服务器,可是总感觉还是不清楚他们之间有什么关系,在用tomcat的时候总出现apache,总感到迷惑,到底谁是主谁是次,因此特意在网上查询了一些这方面的资料,总 ...

  9. Web核心之tomcat汤姆猫

    web相关概念 1. 软件架构 1. C/S:客户端/服务器端 2. B/S:浏览器/服务器端 2. 资源分类 1. 静态资源:所有用户访问后,得到的结果都是一样的,称为静态资源.静态资源可以直接被浏 ...

随机推荐

  1. 一个实体对象不能由多个 IEntityChangeTracker 实例引用。

    错误代码 public bool addSubOptionItem(csModel.cs_Answer answers) { bool result = false; wpe = new csWeiP ...

  2. [转]JAVA泛型通配符T,E,K,V区别,T以及Class<T>,Class<?>的区别

    原文地址:https://www.jianshu.com/p/95f349258afb 1. 先解释下泛型概念 泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被 ...

  3. 一、安装MYSQL

    数据库就是数据的仓库.MYSQL数据库软件它也是一个独立的软件.它是和PHP配合最好的一种数据库.MYSQL数据库也可以作为其它编程语言的数据源. MYSQL的官方网站:http://www.mysq ...

  4. JS监听页面----无鼠标键盘动作,自动跳页

    function ScreenSaver(settings){ this.settings = settings; this.nTimeout = this.settings.timeout; doc ...

  5. jquery 异步处理

    <!DOCTYPE html> <head> <script type="text/javascript" src="jquery-1.12 ...

  6. mssqlserver获取表说明和行数

    SELECT a.*,t.rows FROM ( ) ) AS a left join (, )) ) AS t ON a.表名=t.name

  7. 唯一id算法

    https://blog.csdn.net/guodongcc322/article/details/55211273 https://blog.csdn.net/weixin_36751895/ar ...

  8. iOS 实时音频采集与播放Audio Unit使用

    前言 在iOS中有很多方法可以进行音视频采集.如 AVCaptureDevice, AudioQueue以及Audio Unit.其中 Audio Unit是最底层的接口,它的优点是功能强大,延迟低; ...

  9. 6 ways to import data into SQL Server

    I’m going to go over some methods to import data from text files into SQL Server today. The particul ...

  10. 树莓派 NOOBS 安装系统

    Raspberry Pi Foundation发布了一个名为“New Out of Box Software”(NOOBS)的工具,可以用来方便的安装系统,让我们尝试一下这个新的安装工具. 以我的树莓 ...