SVProgressHUD源码学习

看完后对SVProgressHUD改进的想法

替换成MBProgressHUD

替换后的好处

首先在界面消失时 SVProgressHUD 需要调用dismiss的巨大缺陷 并不存在。

在view中加入的单个MBProgressHUD可以通过HUDForView方法找到其引用。有多个HUD的复杂情况,也可以通过增加属性的方式来进行获取其引用。


如果替换,会遇到的问题

最复杂的情况是:网络请求框架使用的SVProgressHUD。

存在问题:

拿不到self.view

会有多个网络请求同时进行

在一个界面发起的请求,退出那个界面时要让HUD消失

解决方案:

每一个需要HUD的网络请求都要对应一个View。

只需要在网络请求时把对应的View传进去。这样的话,只需要修改网络请求框架。网络请求开始时,在对应的View中添加HUD。网络请求结束时,隐藏对应View中的那个HUD。这样就不会存在后两个问题。


具体修改方案



以下是做出判断的具体过程



SVProgressHUD 轻量易用。使用以下简单清晰的API,便完成了整个项目的等待提示。

[SVProgressHUD setBackgroundColor:[UIColor colorWithRed:0 green:0 blue:0 alpha:0.5]];

[SVProgressHUD setForegroundColor:[UIColor whiteColor]];

[SVProgressHUD show];

[SVProgressHUD showWithStatus:@" "];

[SVProgressHUD showSuccessWithStatus:@" "];

[SVProgressHUD showErrorWithStatus:@" "];

[SVProgressHUD showWithMaskType:SVProgressHUDMaskTypeClear];

[SVProgressHUD dismiss];


使用后存在的问题

[SVProgressHUD dismiss] 在项目中满天飞。而且dismiss和show不存在绑定关系,导致等待框莫名消失。

SVProgressHUD使用的是单例模式。整个项目里只能同时存在一个等待框。当多个界面、多个提示需要等待框时,前一个等待框必然会消失。


阅读源码的期望

为每一个 show分配一个 key。dismiss能够根据key来取消

摆脱单例模式,把等待框和View绑定在一起。多个View可以拥有多个等待框。

自定义等待框动画


阅读源码时想了解的

等待框被加到了哪里,window?

屏幕遮罩是怎么做的?

动画效果是怎么做的?

还有什么没用到的高级功能?


阅读源码中。。。

SVProgressHUD源码学习_第1张图片
获取顶层Window
加入到 指定容器或者最上层Window

界面层次结构

ContainView/frontWindow ->controlView -> self -> backgroundView and hudView 

SVProgressHUD源码学习_第2张图片
设置遮罩效果
SVProgressHUD源码学习_第3张图片
像条蛇一样的转圈动画,该动画存在于一个自定义View中。可重写
SVProgressHUD源码学习_第4张图片
每一次show,activityCount会加1。dismiss操作会使activityCount = 0|只在这里使用了。感觉做的不够好,pop后没有上一个等待框的属性来恢复上一次的状态

改不动的感觉,了解一下MBProgressHUD先


SVProgressHUD源码学习_第5张图片
各种样式都很美观,看起来很不错


//初始化方法

MBProgressHUD *hud = [MBProgressHUD HUDForView:self.navigationController.view];

MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.navigationController.view animated:YES];

MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view.window animated:YES];

//各种属性可以根据需要加

hud.label.text = @"";

hud.detailsLabel.text = @"";

hud.contentColor = [UIColor colorWithRed:0.f green:0.6f blue:0.7f alpha:1.f];

hud.backgroundView.style = MBProgressHUDBackgroundStyleSolidColor;

hud.backgroundView.color = [UIColor colorWithWhite:0.f alpha:0.1f];


//还有各种模式可以选择

//很好的一点是一个hud可以在不同模式之间各种切换显示

//这样可以解决网络请求时,先是等待框再变成提示框的问题

hud.mode = MBProgressHUDModeDeterminate;

NSProgress *progressObject = [NSProgress progressWithTotalUnitCount:100];

hud.progressObject = progressObject;

[hud.button setTitle:@""  forState:UIControlStateNormal];

[hud.button addTarget:progressObject action:@selector(cancel) forControlEvents:UIControlEventTouchUpInside];


hud.mode = MBProgressHUDModeAnnularDeterminate;


hud.mode = MBProgressHUDModeCustomView;

UIImage *image = [[UIImage imageNamed:@"Checkmark"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];

hud.customView = [[UIImageView alloc] initWithImage:image];

hud.square = YES;


hud.mode = MBProgressHUDModeText;

hud.label.text = @"";

hud.offset = CGPointMake(0.f, MBProgressMaxOffset);


hud.mode = MBProgressHUDModeDeterminate;

[hud.button setTitle:@"" forState:UIControlStateNormal];

[hud.button addTarget:self action:@selector(cancelWork:) forControlEvents:UIControlEventTouchUpInside];


//隐藏

[hud hideAnimated:YES];

[hud hideAnimated:YES afterDelay:3.f];

体验感想:

易用性不逊色于SVProgressHUD。多的一步操作是 需要自己管理hud属性,但在不造成混乱所带来的好处面前,多的这一步不算什么。

可选模式涵盖了各种想得到想不到的需求,而且提供了自定义View,扩展不需要修改源代码。


阅读源代码前想知道的

MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.navigationController.view animated:YES];

MBProgressHUD *hud = [MBProgressHUD HUDForView:self.navigationController.view];

两段代码同时使用,得到的第二个hud是指向第一个hud吗?


在window加多个hud会怎么样?


阅读MBProgressHUD源代码中。。。

hud.userInteractionEnabled = NO 可以使底部界面能响应


SVProgressHUD源码学习_第6张图片
隐藏的是 view里最顶上的HUD


SVProgressHUD源码学习_第7张图片
获取view里最顶上的hud。并不是重新初始化一个


SVProgressHUD源码学习_第8张图片
获取最顶层hud的方法

代码写的很规范,层次结构简单清晰。



你可能感兴趣的:(SVProgressHUD源码学习)