生活随笔
收集整理的這篇文章主要介紹了
使用SVProgressHUD时加入自定义Gif图片
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
??? 在 iOS 開發(fā)中說(shuō)到指示器用的最多的便是 MBP 和 SVP 了,針對(duì)于這兩個(gè)第三方我個(gè)人還是比較偏向后者。比較 MBP 而言 SVP的作者封裝的更加完美一些,接口的設(shè)計(jì)和使用也更為簡(jiǎn)單,但是在使用時(shí)還是有些場(chǎng)景無(wú)法滿足,這篇文章我只是想談?wù)剬?duì)于把自定義的 GIF 圖片與 SVProgressHUD 結(jié)合使用的個(gè)人想法。首先我們先看看下面的一段代碼:
- (void)viewDidLoad {[super viewDidLoad];// 我們通過 SVProgressHUD 提供的類方法 + (void)show; 可以實(shí)現(xiàn)最簡(jiǎn)單的加載指示效果[SVProgressHUD show];}- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{// 移除指示器[SVProgressHUD dismiss];
}
??? 效果圖如下 :
? ? 那這個(gè)不斷旋轉(zhuǎn)的圓圈效果是 SVProgressHUD 自帶的Gif圖片嗎?通過多 SVP 中的資源包的查看得知,這個(gè)會(huì)動(dòng)的圓圈并不是Gif圖片,而是畫出來(lái)的。但是 SVP 是否給我們提供可以傳入 UIImage 對(duì)象的方法或是屬性接口呢?我們?cè)賮?lái)看看下面的代碼和效果:
方案一:通過方法實(shí)現(xiàn)
- (void)viewDidLoad {[super viewDidLoad];// 我們讓程序已啟動(dòng) 就顯示指示器// 設(shè)置顯示最小時(shí)間 以便觀察效果[SVProgressHUD setMinimumDismissTimeInterval:MAXFLOAT];// 果然 我們發(fā)現(xiàn)了一個(gè)可以傳入圖片和文字的方法[SVProgressHUD showImage:[UIImage imageNamed:@"testImage@2x.gif"] status:@"努力加載中"];}
方案一:通過屬性實(shí)現(xiàn)
- (void)viewDidLoad {[super viewDidLoad];// 設(shè)置顯示最小時(shí)間 以便觀察效果[SVProgressHUD setMinimumDismissTimeInterval:MAXFLOAT];// 設(shè)置屬性 @property (strong, nonatomic) UIImage *infoImage [SVProgressHUD setInfoImage:[UIImage imageNamed:@"testImage@2x.gif"]];[SVProgressHUD showInfoWithStatus:@"努力加載中"];}
但是效果卻不是我們想要的,我們發(fā)現(xiàn)原本是 Gif 可以轉(zhuǎn)動(dòng)的圖片不能動(dòng)了... 效果如下 :
??? 其實(shí) Gif 圖片能動(dòng)的本質(zhì)是幀動(dòng)畫,我們?cè)诶密浖谱?Gif 圖片的時(shí)候中間有一個(gè)步驟是 : 比如將一個(gè)小視頻分割成N張圖片,然后按照每張圖片設(shè)置好的幀時(shí)長(zhǎng)來(lái)進(jìn)行連貫播放,優(yōu)化后就形成了我們所熟知的 Gif 圖片了。那么我們?cè)?iOS 開發(fā)過程中能否將原有的 Gif 圖片轉(zhuǎn)換為N張靜態(tài)圖片的數(shù)組,再由 UIImage 提供的幀動(dòng)畫方法生成可以動(dòng)的 UIImage對(duì)象。根據(jù)這個(gè)想法,我寫了下面的一個(gè)分類 :
??? UIImage+GIF.h
#import <UIKit/UIKit.h>
typedef void (^GIFimageBlock)(UIImage *GIFImage);@interface UIImage (GIF)/** 根據(jù)本地GIF圖片名 獲得GIF image對(duì)象 */
+ (UIImage *)imageWithGIFNamed:(NSString *)name;/** 根據(jù)一個(gè)GIF圖片的data數(shù)據(jù) 獲得GIF image對(duì)象 */
+ (UIImage *)imageWithGIFData:(NSData *)data;/** 根據(jù)一個(gè)GIF圖片的URL 獲得GIF image對(duì)象 */
+ (void)imageWithGIFUrl:(NSString *)url and:(GIFimageBlock)gifImageBlock;@end
??? UIImage+GIF.m
#import "UIImage+GIF.h"
#import <ImageIO/ImageIO.h>@implementation UIImage (GIF)+ (UIImage *)imageWithGIFData:(NSData *)data
{if (!data) return nil;CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);size_t count = CGImageSourceGetCount(source);UIImage *animatedImage;if (count <= 1) {animatedImage = [[UIImage alloc] initWithData:data];} else {NSMutableArray *images = [NSMutableArray array];NSTimeInterval duration = 0.0f;for (size_t i = 0; i < count; i++) {// 拿出了Gif的每一幀圖片CGImageRef image = CGImageSourceCreateImageAtIndex(source, i, NULL);//Learning... 設(shè)置動(dòng)畫時(shí)長(zhǎng) 算出每一幀顯示的時(shí)長(zhǎng)(幀時(shí)長(zhǎng))NSTimeInterval frameDuration = [UIImage sd_frameDurationAtIndex:i source:source];duration += frameDuration;// 將每幀圖片添加到數(shù)組中[images addObject:[UIImage imageWithCGImage:image scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp]];// 釋放真圖片對(duì)象CFRelease(image);}// 設(shè)置動(dòng)畫時(shí)長(zhǎng)if (!duration) {duration = (1.0f / 10.0f) * count;}animatedImage = [UIImage animatedImageWithImages:images duration:duration];}// 釋放源Gif圖片CFRelease(source);return animatedImage;
}+ (UIImage *)imageWithGIFNamed:(NSString *)name
{NSUInteger scale = (NSUInteger)[UIScreen mainScreen].scale;return [self GIFName:name scale:scale];
}+ (UIImage *)GIFName:(NSString *)name scale:(NSUInteger)scale
{NSString *imagePath = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"%@@%zdx", name, scale] ofType:@"gif"];if (!imagePath) {(scale + 1 > 3) ? (scale -= 1) : (scale += 1);imagePath = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"%@@%zdx", name, scale] ofType:@"gif"];}if (imagePath) {// 傳入圖片名(不包含@Nx)NSData *imageData = [NSData dataWithContentsOfFile:imagePath];return [UIImage imageWithGIFData:imageData];} else {imagePath = [[NSBundle mainBundle] pathForResource:name ofType:@"gif"];if (imagePath) {// 傳入的圖片名已包含@Nx or 傳入圖片只有一張 不分@NxNSData *imageData = [NSData dataWithContentsOfFile:imagePath];return [UIImage imageWithGIFData:imageData];} else {// 不是一張GIF圖片(后綴不是gif)return [UIImage imageNamed:name];}}
}+ (void)imageWithGIFUrl:(NSString *)url and:(GIFimageBlock)gifImageBlock
{NSURL *GIFUrl = [NSURL URLWithString:url];if (!GIFUrl) return;dispatch_async(dispatch_get_global_queue(0, 0), ^{NSData *CIFData = [NSData dataWithContentsOfURL:GIFUrl];// 刷新UI在主線程dispatch_async(dispatch_get_main_queue(), ^{gifImageBlock([UIImage imageWithGIFData:CIFData]);});});}#pragma mark - <關(guān)于GIF圖片幀時(shí)長(zhǎng)(Learning...)>+ (float)sd_frameDurationAtIndex:(NSUInteger)index source:(CGImageSourceRef)source {float frameDuration = 0.1f;CFDictionaryRef cfFrameProperties = CGImageSourceCopyPropertiesAtIndex(source, index, nil);NSDictionary *frameProperties = (__bridge NSDictionary *)cfFrameProperties;NSDictionary *gifProperties = frameProperties[(NSString *)kCGImagePropertyGIFDictionary];NSNumber *delayTimeUnclampedProp = gifProperties[(NSString *)kCGImagePropertyGIFUnclampedDelayTime];if (delayTimeUnclampedProp) {frameDuration = [delayTimeUnclampedProp floatValue];}else {NSNumber *delayTimeProp = gifProperties[(NSString *)kCGImagePropertyGIFDelayTime];if (delayTimeProp) {frameDuration = [delayTimeProp floatValue];}}// Many annoying ads specify a 0 duration to make an image flash as quickly as possible.// We follow Firefox's behavior and use a duration of 100 ms for any frames that specify// a duration of <= 10 ms. See <rdar://problem/7689300> and <http://webkit.org/b/36082>// for more information.if (frameDuration < 0.011f) {frameDuration = 0.100f;}CFRelease(cfFrameProperties);return frameDuration;
}
??? 那么引入這個(gè)分類,我們看看是否能達(dá)到預(yù)期的效果,代碼 AND 效果圖如下 :
- (void)viewDidLoad {[super viewDidLoad];// 設(shè)置顯示最小時(shí)間 以便觀察效果[SVProgressHUD setMinimumDismissTimeInterval:MAXFLOAT];// 設(shè)置背景顏色為透明色[SVProgressHUD setBackgroundColor:[UIColor clearColor]];// 利用SVP提供類方法設(shè)置 通過UIImage分類方法返回的動(dòng)態(tài)UIImage對(duì)象[SVProgressHUD showImage:[UIImage imageWithGIFNamed:@"loading01"] status:@"正在加載中"];}
??? 效果圖如下 :
??? 至此我們簡(jiǎn)單的實(shí)現(xiàn)了,使用 SVProgressHUD 時(shí)加入我們自定義的 Gif 圖片。大家有更好的方法也可以相互討論,共同提高,謝謝支持我的博客 : http://blog.csdn.net/im_loser 。
總結(jié)
以上是生活随笔為你收集整理的使用SVProgressHUD时加入自定义Gif图片的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。