热门标签 | HotTags
当前位置:  开发笔记 > 后端 > 正文

使用SVProgressHUD时加入自定义Gif图片

在iOS开发中说到指示器用的最多的便是MBP和SVP了,针对于这两个第三方我个人还是比较偏向后者。比较MBP而言SVP的作者封装的更加完美一些,接口的设

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

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

    效果图如下 :

方案一:通过属性实现

- (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
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 @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 }+ (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&#39;s behavior and use a duration of 100 ms for any frames that specify// a duration of <= 10 ms. See and // 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 。





推荐阅读
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • iOS Swift中如何实现自动登录?
    本文介绍了在iOS Swift中如何实现自动登录的方法,包括使用故事板、SWRevealViewController等技术,以及解决用户注销后重新登录自动跳转到主页的问题。 ... [详细]
  • 本文介绍了iOS开发中检测和解决内存泄漏的方法,包括静态分析、使用instruments检查内存泄漏以及代码测试等。同时还介绍了最能挣钱的行业,包括互联网行业、娱乐行业、教育行业、智能行业和老年服务行业,并提供了选行业的技巧。 ... [详细]
  • IhaveconfiguredanactionforaremotenotificationwhenitarrivestomyiOsapp.Iwanttwodiff ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • 本文介绍了在Vue项目中如何结合Element UI解决连续上传多张图片及图片编辑的问题。作者强调了在编码前要明确需求和所需要的结果,并详细描述了自己的代码实现过程。 ... [详细]
  • Html5-Canvas实现简易的抽奖转盘效果
    本文介绍了如何使用Html5和Canvas标签来实现简易的抽奖转盘效果,同时使用了jQueryRotate.js旋转插件。文章中给出了主要的html和css代码,并展示了实现的基本效果。 ... [详细]
  • C# WPF自定义按钮的方法
    本文介绍了在C# WPF中实现自定义按钮的方法,包括使用图片作为按钮背景、自定义鼠标进入效果、自定义按压效果和自定义禁用效果。通过创建CustomButton.cs类和ButtonStyles.xaml资源文件,设计按钮的Style并添加所需的依赖属性,可以实现自定义按钮的效果。示例代码在ButtonStyles.xaml中给出。 ... [详细]
  • 本文介绍了在Mac上安装Xamarin并使用Windows上的VS开发iOS app的方法,包括所需的安装环境和软件,以及使用Xamarin.iOS进行开发的步骤。通过这种方法,即使没有Mac或者安装苹果系统,程序员们也能轻松开发iOS app。 ... [详细]
  • 本文介绍了Sencha Touch的学习使用心得,主要包括搭建项目框架的过程。作者强调了使用MVC模式的重要性,并提供了一个干净的引用示例。文章还介绍了Index.html页面的作用,以及如何通过链接样式表来改变全局风格。 ... [详细]
  • 本文详细介绍了Android中的坐标系以及与View相关的方法。首先介绍了Android坐标系和视图坐标系的概念,并通过图示进行了解释。接着提到了View的大小可以超过手机屏幕,并且只有在手机屏幕内才能看到。最后,作者表示将在后续文章中继续探讨与View相关的内容。 ... [详细]
  • 本文介绍了Cocos2dx学习笔记中的更新函数scheduleUpdate、进度计时器CCProgressTo和滚动视图CCScrollView的用法。详细介绍了scheduleUpdate函数的作用和使用方法,以及schedule函数的区别。同时,还提供了相关的代码示例。 ... [详细]
author-avatar
无语我去_296
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有