iPhone SDK提供了多种动画手段,UIView、UIImageView和CALayer都支持动画。但如何处理常见的gif动画呢?UIWebView提供了答案,代码如下:1. 使用UIWebView播放 // 设定位置和大小 CGRect frame = CGRectMake(50,50,0,0); frame.size = [UIImage p_w_picpathNamed:@"guzhang.gif"].size; // 读取gif图片数据 NSData *gif = [NSData dataWithContentsOfFile: [[NSBundle mainBundle] pathForResource:@"guzhang" ofType:@"gif"]]; // view生成 UIWebView *webView = [[UIWebView alloc] initWithFrame:frame]; webView.userInteractionEnabled = NO;//用户不可交互 [webView loadData:gif MIMEType:@"p_w_picpath/gif" textEncodingName:nil baseURL:nil]; [self.view addSubview:webView]; [webView release];2. 将gif图片分解成多张png图片,使用UIImageView播放。代码如下:UIImageView *gifImageView = [[UIImageView alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; NSArray *gifArray = [NSArray arrayWithObjects:[UIImage p_w_picpathNamed:@"1"], [UIImage p_w_picpathNamed:@"2"], [UIImage p_w_picpathNamed:@"3"], [UIImage p_w_picpathNamed:@"4"], [UIImage p_w_picpathNamed:@"5"], [UIImage p_w_picpathNamed:@"6"], [UIImage p_w_picpathNamed:@"7"], [UIImage p_w_picpathNamed:@"8"], [UIImage p_w_picpathNamed:@"9"],nil]; gifImageView.animationImages = gifArray; //动画图片数组 gifImageView.animationDuration = 5; //执行一次完整动画所需的时长 gifImageView.animationRepeatCount = 1; //动画重复次数 [gifImageView startAnimating]; [self.view addSubview:gifImageView]; [gifImageView release];
3. 本次实现gif动画播放是通过将动画文件读取到CGImageSourceRef,然后用NSTimer来播放的。
代码如下:
首先是头文件
#import#import #import @interface GifView : UIView {CGImageSourceRef gif; // 保存gif动画NSDictionary *gifProperties; // 保存gif动画属性size_t index; // gif动画播放开始的帧序号size_t count; // gif动画的总帧数NSTimer *timer; // 播放gif动画所使用的timer}- (id)initWithFrame:(CGRect)frame filePath:(NSString *)filePath;- (void)stopGif;@end
接下来是实现
#import "GifView.h" #import@implementation GifView - (id)initWithFrame:(CGRect)frame filePath:(NSString *)filePath { self = [super initWithFrame:frame]; if (self) { NSDictionary *gifLoopCount = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:0] forKey:(NSString *)kCGImagePropertyGIFLoopCount]; gifProperties = [[NSDictionary dictionaryWithObject:gifLoopCount forKey:(NSString *)kCGImagePropertyGIFDictionary] retain]; gif = CGImageSourceCreateWithURL((CFURLRef)[NSURL fileURLWithPath:path], (CFDictionaryRef)gifProperties); count =CGImageSourceGetCount(gif); timer = [NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(play) userInfo:nil repeats:YES]; [timer fire]; } return self; } -(void)play { index ++; index = index%count; CGImageRef ref = CGImageSourceCreateImageAtIndex(gif, index, (CFDictionaryRef)gifProperties); self.layer.contents = (id)ref; CFRelease(ref); } - (void)dealloc { NSLog(@"dealloc"); CFRelease(gif); [gifProperties release]; [super dealloc]; } - (void)stopGif { [timer invalidate]; timer = nil; } @end
这个类比较简单,在方法
- (id)initWithFrame:(CGRect)frame filePath:(NSString *)filePath
调用结束就开始播放动画,如果需要用户指定何时播放的话,只需要把timer的开始放到合适的位置。通过对CFDictonaryRaf 也就是gifProperties的改变,我们还可以控制动画是否循环播放以及循环多少次停止。
通过对index的改变也可以控制动画从某帧开始播放。同理,同时改变index和count的话,也可以控制从某帧到某帧的播放。
注:必须调用方法
- (void)stopGif
之后才可以退出这个类。否则timer不会关闭,产生内存泄露。另注:需要QuartzCore.framework;MobileCoreServices.framework;ImageIO.framework 这三个framework的支持
4. SCGIFImageView是一个开源的GIF图片动画显示控件,通过将GIF的每一帧都取出来生成UIImage对象存放在一个数组中,然后使用NSTimer进行动画轮转。
示例代码:
NSString* filePath = [[NSBundle mainBundle] pathForResource:@"1.gif" ofType:nil]; NSData* p_w_picpathData = [NSData dataWithContentsOfFile:filePath]; SCGIFImageView* gifImageView = [[[SCGIFImageView alloc] initWithFrame:self.view.bounds] autorelease]; [gifImageView setData:p_w_picpathData]; [self.view addSubview:gifImageView];