close
当前位置: 物联网在线 > 技术文库 > ios >

MBProgressHUD源码解析(2)

下面开始分别讲解 show 系列的方法和 hide 系列的方法。

3.1 show系列方法 + (instancetype)showHUDAddedTo:(UIView *)view animated:(BOOL)animated { MBProgressHUD *hud = [[self alloc] initWithView:view];// 接着调用 [self initWithFrame:view.bounds]:根据传进来的view的frame来设定自己的frame hud.removeFromSuperViewOnHide = YES;//removeFromSuperViewOnHide 应该是一个标记,表明HUD自己处于“应该被移除的状态” [view addSubview:hud];//在view上将自己的实例添加上去 [hud showAnimated:animated]; return hud; } //调用showAnimated: - (void)showAnimated:(BOOL)animated { MBMainThreadAssert(); [self.minShowTimer invalidate];//取消当前的minShowTimer self.useAnimation = animated;//设置animated状态 self.finished = NO;//添加标记:表明当前任务仍在进行 // 如果设定了graceTime,就要推迟HUD的显示 if (self.graceTime > 0.0) { NSTimer *timer = [NSTimer timerWithTimeInterval:self.graceTime target:self selector:@selector(handleGraceTimer:) userInfo:nil repeats:NO]; [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; self.graceTimer = timer; } // ... otherwise show the HUD immediately else { [self showUsingAnimation:self.useAnimation]; } } //self.graceTimer触发的方法 - (void)handleGraceTimer:(NSTimer *)theTimer { // Show the HUD only if the task is still running if (!self.hasFinished) { [self showUsingAnimation:self.useAnimation]; } } //所有的show方法最终都会走到这个方法 - (void)showUsingAnimation:(BOOL)animated { // Cancel any previous animations : 移走所有的动画 [self.bezelView.layer removeAllAnimations]; [self.backgroundView.layer removeAllAnimations]; // Cancel any scheduled hideDelayed: calls :取消delay的timer [self.hideDelayTimer invalidate]; //记忆开始的时间 self.showStarted = [NSDate date]; self.alpha = 1.f; // Needed in case we hide and re-show with the same NSProgress object attached. [self setNSProgressDisplayLinkEnabled:YES]; if (animated) { [self animateIn:YES withType:self.animationType completion:NULL]; } else { //方法弃用警告 #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" self.bezelView.alpha = self.opacity; #pragma clang diagnostic pop self.backgroundView.alpha = 1.f; } }

我们可以看到,无论是类方法的show方法,还是对象方法的show方法,而且无论是触发了 graceTimer 还是没有触发,最后都会走到 showUsingAnimation: 方法来让HUD显示出来。

这里补充讲解一下NSProgress的监听方法:

- (void)setNSProgressDisplayLinkEnabled:(BOOL)enabled { // 这里使用 CADisplayLink 来刷新progress的变化。因为如果使用kvo机制来监听的话可能会非常消耗主线程(因为频率可能非常快)。 if (enabled && self.progressObject) { // Only create if not already active. if (!self.progressObjectDisplayLink) { self.progressObjectDisplayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateProgressFromProgressObject)]; } } else { //不刷新 self.progressObjectDisplayLink = nil; } }

CADisplayLink是一个能让我们以和屏幕刷新率同步的频率将特定的内容画到屏幕上的定时器类。 CADisplayLink以特定模式注册到runloop后, 每当屏幕显示内容刷新结束的时候,runloop就会向 CADisplayLink指定的target发送一次指定的selector消息, CADisplayLink类对应的selector就会被调用一次。

3.2 hide系列方法 + (BOOL)hideHUDForView:(UIView *)view animated:(BOOL)animated { MBProgressHUD *hud = [self HUDForView:view];//获取当前view的最前为止的HUD if (hud != nil) { hud.removeFromSuperViewOnHide = YES; [hud hideAnimated:animated]; return YES; } return NO; } + (MBProgressHUD *)HUDForView:(UIView *)view { NSEnumerator *subviewsEnum = [view.subviews reverseObjectEnumerator]; //倒叙排序 for (UIView *subview in subviewsEnum) { if ([subview isKindOfClass:self]) { return (MBProgressHUD *)subview; } } return nil; } - (void)hideAnimated:(BOOL)animated { MBMainThreadAssert(); [self.graceTimer invalidate]; self.useAnimation = animated; self.finished = YES; //如果设定了HUD最小显示时间,那就需要判断最小显示时间和已经经过的时间的大小 if (self.minShowTime > 0.0 && self.showStarted) { NSTimeInterval interv = [[NSDate date] timeIntervalSinceDate:self.showStarted]; //如果最小显示时间比较大,则暂时不触发HUD的隐藏,而是启动一个timer,再经过二者的时间差的时间之后再触发隐藏 if (interv < self.minShowTime) { NSTimer *timer = [NSTimer timerWithTimeInterval:(self.minShowTime - interv) target:self selector:@selector(handleMinShowTimer:) userInfo:nil repeats:NO]; [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; self.minShowTimer = timer; return; } } //如果最小显示时间比较小,则立即将HUD隐藏 [self hideUsingAnimation:self.useAnimation]; } //self.minShowTimer触发的方法 - (void)handleMinShowTimer:(NSTimer *)theTimer { [self hideUsingAnimation:self.useAnimation]; } - (void)hideUsingAnimation:(BOOL)animated { if (animated && self.showStarted) { //隐藏时,将showStarted设为nil self.showStarted = nil; [self animateIn:NO withType:self.animationType completion:^(BOOL finished) { [self done]; }]; } else { self.showStarted = nil; self.bezelView.alpha = 0.f; self.backgroundView.alpha = 1.f; [self done]; } }
(责任编辑:ioter)

用户喜欢...

stm32 PID调速控制直流无刷电机+ 源码

笔记 具备知识,stm32基础,了解无刷直流电机原理,pid控制原理 工具: 无刷直流电机:12v电源驱动,50HZ,占空比为5%的pwm波2秒以上解锁电调,再将占空比改为6%,则电机正常运行,改变占空比...


IBM解析2018年最流行的五项IoT趋势

2017年,物联网技术(loT)为传统行业带来了变革的风声和兴奋的议论。这是一场实质性的转变。我们已经能够看到,几乎所有的行业都在投资物联网,而且其中的佼佼者已经开始迅速采取行...


自动扫地机器人好用吗?智能特性全面解析

生活在如今这样一个节奏快、工作压力大的时代,我们的压力也是越发的大了,但是人类的智慧是强大的,智能家居...


深度解析FPGA四大设计要点

FPGA的用处比我们平时想象的用处更广泛,原因在于其中集成的模块种类更多,而不仅仅是原来的简单逻辑单元(LE)。早期的FPGA相对比较简单,所有的功能单元仅仅由管脚、内部buffer、LE、RAM构...


从图像到知识:深度神经网络实现图像理解的原理解析

摘要:本文将详细解析深度神经网络识别图形图像的基本原理。针对卷积神经网络,本文将详细探讨网络中每一层在图像识别中的原理和作用,例如卷积层(convolutional layer),采样层(pooling la...


单片机最小系统解析(电源、晶振和复位电路)

我们在学习过程中,很多指标都是直接用的概念指标,比如我们说 +5 V 代表1,GND 代表0等等。但在实际电路中的电压值并不是完全精准的,那这些指标允许范围是什么呢?随着我们所学的内容...


技术解析:微流控芯片为什么这样强大?

从1990年Manz等人首次提出了微型全分析系统的概念,到2003年Forbes杂志将微流控技术评为影响人类未来15件最重要的发明之一,微流控技术得到了飞速的发展,其中的微流控芯片技术作为当前分...


解析单片机与CPU的区别

多人都认为,单机片和CPU不是属于两种不同的东西吗?他们怎么可以拿来比较,其实有专业人士就知道单机片和CPU 的关系可以说是十分的密切。本文来分享一下,他们到底隐藏着什么秘密。...


陆金所计葵生:深度解析大数据和AI对未来金融影响

陆金所联席董事长兼CEO计葵生在北京大学数字金融研究中心「数字金融的中国时代」第二届年会上发表主题演讲,深...


滴滴插件化方案 VirtualApk 源码解析

之前一直没有写过插件化相关的博客,刚好最近滴滴和360分别开源了自家的插件化方案,赶紧学习下,写两篇博客,第一篇是滴滴的方案: https://github.com/didi/VirtualAPK 那么其中的难点很明显是...