读源码系列----MBProgressHUD(加载等待框)
来源:互联网 发布:标识符c语言 编辑:程序博客网 时间:2024/05/19 07:41
阅读本文前,请先去下载源代码(传送门)
MBProgressHUD是一个iOS的类,当等待后台进程执行时,可以显示出一个包含指示器或者标签的半透明的HUD。HUD是UIKit包中不允许开发者使用的UIProgressHUD的替代品。
使用前提
MBProgressHUD可以以ARC或者non-ARC方式运行在iOS的任何版本,它使用到下列Cocoa Touch框架
- Foundation.framework
- UIKit.framework
- CoreGraphics.framework
我们从MBProgressHUD.h看起,首先MBProgressHUD继承子UIView,它具有View的特性,其头文件中,定义的枚举类型MBProgressHUDMode和MBProgressHUDAnimation,分别对应不同的加载等待框样式和消失动画类型。通过接下来的宏定义,来标志ARC和non-ARC模式及对BLOCK的支持。通过类方法+ (MBProgressHUD *)showHUDAddedTo:(UIView *)view animated:(BOOL)animated; 或者通过对象方法alloc及initWithView可以获得MBProgressHUD对象,可以通过MBProgressHUD的delegate属性,将遵循MBProgressHUDDelegate协议的对象,设为委托,在MBProgressHUD将要隐藏时回调。
在程序遇到异步或者耗时较长的任务需要执行时,可以使用- (void)showWhileExecuting:(SEL)method onTarget:(id)target withObject:(id)object animated:(BOOL)animated;方法,“锁住“主界面,并显示加载等待框。重点变在该函数内部,我们看一下:
- (void)showWhileExecuting:(SEL)method onTarget:(id)target withObject:(id)object animated:(BOOL)animated {methodForExecution = method;targetForExecution =MB_RETAIN(target);objectForExecution =MB_RETAIN(object);// Launch execution in new threadself.taskInProgress =YES;[NSThreaddetachNewThreadSelector:@selector(launchExecution)toTarget:selfwithObject:nil];// Show HUD view[selfshow:animated];}
首先,我们将要执行的任务及目标对象传入后,MB_RETAIN实际只是宏,在之前说的那段头文件中,在non-ARC下,它将先将target和object的内存计数加1,熟悉内存管理的应该知道,接到参数后先retain,才能防止对象被提前释放。接着使用NSThread开一个线程,这是重点,现在有了新的一条线程,他将去执行我们的传进来的任务,可不让任务在主线程中调用,这样才不会阻塞主线程。新线程发消息给launchExecution。
- (void)launchExecution {@autoreleasepool {#pragma clang diagnostic push#pragma clang diagnostic ignored "-Warc-performSelector-leaks"// Start executing the requested task[targetForExecutionperformSelector:methodForExecutionwithObject:objectForExecution];#pragma clang diagnostic pop// Task completed, update view in main thread (note: view operations should// be done only in the main thread)[selfperformSelectorOnMainThread:@selector(cleanUp)withObject:nilwaitUntilDone:NO];}}
targetForExecution完成具体任务的执行,这时候该线程在一直执行我们的任务,performSelectorOnMainThread的意思是在主线程执行cleanUp,所以当我们任务在其他线程执行完,回到主线程时,执行cleanUp。
cleanUp执行一些release和赋值nil操作后,将执行- (void)hide:(BOOL)animated这个将去执行触发动画效果的方法,接着将调用- (void)done,在done中有一段这样的代码
if ([delegaterespondsToSelector:@selector(hudWasHidden:)]) {[delegateperformSelector:@selector(hudWasHidden:)withObject:self];}
向我们代理的对象发送hudWasHidden:消息,如果之前设置这确,便可以响应。
在头文件中有
@property (atomic, copy) NSString *labelText;@property (atomic, copy) NSString *detailsLabelText;
我们对这两个NSString类型的属性的赋值,会直接更新界面中的Label,这里使用到的是KVO编程,通过#pragma mark - KVO标记可以查看该部分代码,所有键值信息
- (NSArray *)observableKeypaths {return [NSArray arrayWithObjects:@"mode", @"customView", @"labelText", @"labelFont", @"detailsLabelText", @"detailsLabelFont", @"progress", nil];}
注册键值
- (void)registerForKVO {for (NSString *keyPath in [self observableKeypaths]) {[self addObserver:self forKeyPath:keyPath options:NSKeyValueObservingOptionNew context:NULL];}}
当键值改变时,更新UI
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {if (![NSThread isMainThread]) {[self performSelectorOnMainThread:@selector(updateUIForKeypath:) withObject:keyPath waitUntilDone:NO];} else {[self updateUIForKeypath:keyPath];}}
- 读源码系列----MBProgressHUD(加载等待框)
- 读源码系列----MBProgressHUD(加载等待框)
- 自定义加载等待框(MBProgressHUD)
- 自定义加载等待框(MBProgressHUD)
- iOS开发之自定义加载等待框(MBProgressHUD)
- IOS--─自定义加载等待框(MBProgressHUD)
- 加载等待特效框架 MBProgressHUD
- MBProgressHUD 显示等待框
- MBProgressHUD自定义等待框
- IOS开发UI篇之──自定义加载等待框(MBProgressHUD)
- IOS开发UI篇之──自定义加载等待框(MBProgressHUD)
- IOS开发UI篇之──自定义加载等待框(MBProgressHUD)
- IOS开发UI篇之──自定义加载等待框(MBProgressHUD)
- IOS开发UI篇之──自定义加载等待框(MBProgressHUD)
- IOS开发UI篇之──自定义加载等待框(MBProgressHUD)
- IOS开发UI篇之──自定义加载等待框(MBProgressHUD)
- IOS开发UI篇之──自定义加载等待框(MBProgressHUD)
- iOS自定义加载等待视图-MBProgressHUD
- C++ pair
- Freemarker中遍历List实例
- 将Web应用打包成WAR文件的方法
- 发布iOS应用程序(Application Loader)
- Spring3.1.2与Hibernate4.1.8整合
- 读源码系列----MBProgressHUD(加载等待框)
- 新建网站与新建Asp.Net Web 应用程序的区别
- 我眼中的HBase (入门理解)
- ECHO命令的使用
- jquery表单验证插件 jquery.form.js
- 简约主义—Thunderbird邮件处理
- Android onTouchEvent, onClick及onLongClick的调用机制
- 减少reflow让页面变得更快一点
- Solaris:在Vi文件的时候出现错误: "Terminal too wide"