在 iOS 开发中说到指示器用的最多的便是 MBP 和 SVP 了,针对于这两个第三方我个人还是比较偏向后者。比较 MBP 而言 SVP的作者封装的更加完美一些,接口的设计和使用也更为简单,但是在使用时还是有些场景无法满足,这篇文章我只是想谈谈对于把自定义的 GIF 图片与 SVProgressHUD 结合使用的个人想法。首先我们先看看下面的一段代码:

- (void)viewDidLoad {[super viewDidLoad];// 我们通过 SVProgressHUD 提供的类方法 + (void)show; 可以实现最简单的加载指示效果[SVProgressHUD show];}- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{// 移除指示器[SVProgressHUD dismiss];
}

效果图如下 :

那这个不断旋转的圆圈效果是 SVProgressHUD 自带的Gif图片吗?通过多 SVP 中的资源包的查看得知,这个会动的圆圈并不是Gif图片,而是画出来的。但是 SVP 是否给我们提供可以传入 UIImage 对象的方法或是属性接口呢?我们再来看看下面的代码和效果:

方案一:通过方法实现

- (void)viewDidLoad {[super viewDidLoad];// 我们让程序已启动 就显示指示器// 设置显示最小时间 以便观察效果[SVProgressHUD setMinimumDismissTimeInterval:MAXFLOAT];// 果然 我们发现了一个可以传入图片和文字的方法[SVProgressHUD showImage:[UIImage imageNamed:@"testImage@2x.gif"] status:@"努力加载中"];}

方案一:通过属性实现

- (void)viewDidLoad {[super viewDidLoad];// 设置显示最小时间 以便观察效果[SVProgressHUD setMinimumDismissTimeInterval:MAXFLOAT];// 设置属性 @property (strong, nonatomic) UIImage *infoImage [SVProgressHUD setInfoImage:[UIImage imageNamed:@"testImage@2x.gif"]];[SVProgressHUD showInfoWithStatus:@"努力加载中"];}

但是效果却不是我们想要的,我们发现原本是 Gif 可以转动的图片不能动了... 效果如下 :

其实 Gif 图片能动的本质是帧动画,我们在利用软件制作 Gif 图片的时候中间有一个步骤是 : 比如将一个小视频分割成N张图片,然后按照每张图片设置好的帧时长来进行连贯播放,优化后就形成了我们所熟知的 Gif 图片了。那么我们在 iOS 开发过程中能否将原有的 Gif 图片转换为N张静态图片的数组,再由 UIImage 提供的帧动画方法生成可以动的 UIImage对象。根据这个想法,我写了下面的一个分类 :

UIImage+GIF.h

#import <UIKit/UIKit.h>
typedef void (^GIFimageBlock)(UIImage *GIFImage);@interface UIImage (GIF)/** 根据本地GIF图片名 获得GIF image对象 */
+ (UIImage *)imageWithGIFNamed:(NSString *)name;/** 根据一个GIF图片的data数据 获得GIF image对象 */
+ (UIImage *)imageWithGIFData:(NSData *)data;/** 根据一个GIF图片的URL 获得GIF image对象 */
+ (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... 设置动画时长 算出每一帧显示的时长(帧时长)NSTimeInterval frameDuration = [UIImage sd_frameDurationAtIndex:i source:source];duration += frameDuration;// 将每帧图片添加到数组中[images addObject:[UIImage imageWithCGImage:image scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp]];// 释放真图片对象CFRelease(image);}// 设置动画时长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 - <关于GIF图片帧时长(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;
}

那么引入这个分类,我们看看是否能达到预期的效果,代码 AND 效果图如下 :

- (void)viewDidLoad {[super viewDidLoad];// 设置显示最小时间 以便观察效果[SVProgressHUD setMinimumDismissTimeInterval:MAXFLOAT];// 设置背景颜色为透明色[SVProgressHUD setBackgroundColor:[UIColor clearColor]];// 利用SVP提供类方法设置 通过UIImage分类方法返回的动态UIImage对象[SVProgressHUD showImage:[UIImage imageWithGIFNamed:@"loading01"] status:@"正在加载中"];}

效果图如下 :

至此我们简单的实现了,使用 SVProgressHUD 时加入我们自定义的 Gif 图片。大家有更好的方法也可以相互讨论,共同提高,谢谢支持我的博客 : http://blog.csdn.net/im_loser 。

使用SVProgressHUD时加入自定义Gif图片相关推荐

  1. [待解决]自定义头像时使用vue-cropper进行图片裁剪,得到的是base64格式的图片,如何对接file类型的api接口

    [待解决]自定义头像时使用vue-cropper进行图片裁剪,得到的是base64格式的图片,如何对接file类型的api接口 百度很多都没用,有想法欢迎指点.

  2. VUE:img标签加载图片失败时,显示一张自定义默认图片

    简介 在使用<img />标签时,会遇到图片加载失败(有图片资源路径,但是可能路径拼接不正确.域名失效等)的情况,此时,显示出来的效果看着就很不舒服,就想显示一张默认图片. img加载失败 ...

  3. 鸿蒙os事例代码,鸿蒙HarmonyOS App开发造轮子之自定义圆形图片组件的实例代码

    一.背景 在采用Java配合xml布局编写鸿蒙app页面的时候,发现sdk自带的Image组件并不能将图片设置成圆形,反复了翻阅了官方API手册(主要查阅了Compont和Image相关的API),起 ...

  4. 如何将图片调整为固定大小?怎么自定义压缩图片大小?

    很多平台对用户发布的图片大小是有规定的.如果我们发布的图片太大的话,就需要对图片进行压缩处理了.想要缩小图片kb可以使用压缩图的图片压缩指定大小(图片压缩到指定大小 图片压缩大小至指定kb以下-压缩图 ...

  5. Kotlin实战练习——自定义圆形图片三种实现方式

    Kotlin实战练习--自定义圆形图片三种实现方式 前言 如今Kotlin越来越重要,本人也开始了Kotlin的学习.为了检测学习效果,加深学习印象,同时回顾一下以前的一些知识点,决定从写一个自定义圆 ...

  6. Android自定义九宫格图片展示,类似微信朋友圈

    之前网上也找了很多类似的功能,但是很多放在列表中复用item就出现高度测量是0,出现条目中图片空间不显示问题 这里做了一些优化,解决该问题 具体可参考这篇博客,(这里要感谢博主)不过这个放在列表复用时 ...

  7. 图片不大于100kb怎么调?怎么自定义压缩图片大小?

    在报名职称考试上传照片时通常会有100kb的大小限制,超过了就会导致图片无法上传,出现这种情况我们就需要把图片压缩到100kb以下,那么怎么去自定义压缩图片大小呢?想要把图片缩小到固定尺寸可以用图片压 ...

  8. 分享网页文章到微信时如何自定义缩略图、链接、标题和摘要

    1.分享网页文章到微信时自定义缩略图.链接.标题和摘要的方法: var imgUrl = http://www.gettool.cn/GetwxLink/xxx.jpg';var lineLink = ...

  9. 社保卡电子照片怎么压缩到140KB?如何自定义压缩图片kb?

    我们在相关平台办理电子社保卡时,对证件照片大小会有不能超过140KB的规定,我们需要对不符合要求的图片压缩到140kb以下,有没有什么办法可以自定义压缩图片大小呢?这里我们推荐使用专业的图片压缩指定大 ...

最新文章

  1. MySQL在创建索引之前一定要想到的事情
  2. 带有JSON的杰克逊:无法识别的字段,未标记为可忽略
  3. 为何从单体架构迁移到微服务这么难?
  4. Mysql 批量插入数据的方法
  5. PHP生成缩略图函数
  6. java发送c语言结构体_C语言中结构体直接赋值?
  7. 实验一 线性表的顺序存储与实现_【自考】数据结构中的线性表,期末不挂科指南,第2篇
  8. 【codevs1077】多源最短路
  9. 13. 用hexdump工具分析镜像的16进制代码
  10. s7-1200PLC和第三方扫码枪走以太网通信
  11. 脉动风时程matlab程序,脉动风时程matlab程序.doc
  12. php 检测是否有jmail,asp空间判断jmail组件是否安装或支持的代码
  13. android killer 反编译工具,androidkiller反编译软件使用与踩坑并解决的过程
  14. [iOS]分享文件到QQ好友或微信好友
  15. 【软件测试】软件测试随手记
  16. [首发] 多方位玩转“地平线新发布AIoT开发板——旭日X3派(Sunrise x3 Pi)” 插电!开机!轻松秒杀!
  17. Excel数据透视表排序
  18. SQL到底该怎么发音: S-Q-L or Sequel?
  19. 新入行的软件测试工程师必须知道这7点...
  20. 深圳 不景气_为什么经济不景气会帮助社交网络

热门文章

  1. 睡眠专家的7个建议 让你一夜好眠
  2. webpack的了解及其各种使用
  3. 钉钉企业内部应用授权免登+鉴权
  4. 李峋同款爱心Python代码版来了
  5. 错失4000亿美金!微软做错了什么?
  6. 美国技术人员常用招聘求职网站
  7. arduino 超详细的开发入门指导
  8. php 连续三元,[译] php 中更简洁的三元运算符 ?:
  9. c语言实践报告计算机,c语言实践报告计算机
  10. 利用python删除excel的空白行