前言:
MBProgressHUD,是iOS开发中很经典的一个框架,我们可能每个项目,乃至每个ViewController都能用到,越是常用的控件,就更应该简化其调用方式,来优化我们自己的代码.这里我列举出自己常用封装,也建议各位将自己常用的模式也封装起来.
12月6日更新添加了覆盖navigationBar的形式,以及添加了对navigationController?.navigationBar.isTranslucent属性的判断,实现不同项目的正常显示.
实现效果:
对调用方法进行封装,实现一行代码弹出HUD
实现七种形式:
- 不遮盖navigationBar背景半透明显示文字
- 遮盖navigationBar背景半透明显示文字
- 背景透明显示文字
- 背景透明显示Loading
- 不遮盖navigationBar背景半透明显示Loading
- 遮盖navigationBar背景半透明显示Loading
- 背景透明显示自定义icon+文字
实现方式:
1.新建一个类,并实现创建HUD实例方法.
2.实现显示HUD方法.
3.展示loadingView方法.
4.类Toast只展示文字方法.
5.展示成功,失败类似icon+文字方法.
6.隐藏HUD方法
1.新建一个类,并实现创建HUD实例方法.
/// 创建Hud
///
/// - Parameters:
/// - view: 加载到哪个View展示.
/// - isMask: 是否是蒙层形式,背景半透明.
/// - isTranslucent: 项目中navigationBar是否计算frame,默认是false,如果项目中有调用self.navigationController?.navigationBar.isTranslucent = true则传入true
private class func createHud(view : UIView? = UIApplication.shared.keyWindow, isMask : Bool = false ,isTranslucent: Bool = false) -> MBProgressHUD? {
guard let supview = view ?? UIApplication.shared.keyWindow else {return nil}
let HUD = MBProgressHUD.showAdded(to: supview
, animated: true)
let top = isTranslucent ? 0 : EWScreenInfo.navigationHeight
HUD.frame = CGRect(x: 0, y: top, width: EWScreenInfo.Width, height: EWScreenInfo.Height - top)
HUD.animationType = .zoom
if isMask {
/// 蒙层type,背景半透明.
HUD.backgroundView.color = UIColor(white: 0.0, alpha: 0.4)
} else {
/// 非蒙层type,没有背景.
HUD.backgroundView.color = UIColor.clear
HUD.bezelView.backgroundColor = UIColor(white: 0.0, alpha: 0.9)
HUD.contentColor = UIColor.white
}
HUD.removeFromSuperViewOnHide = true
HUD.show(animated: true)
return HUD
}
/// 创建hud,覆盖navigationbar
///
/// - Parameters:
/// - navigationController: 如果想要覆盖navigationBar则需要传入navigationController
/// - isMask: 是否蒙层覆盖
/// - Returns: hud实例
private class func createHud(navigationController : UINavigationController?, isMask : Bool = false) -> MBProgressHUD? {
guard let navc = navigationController else {return nil}
guard let supview = navc.view else {return nil}
let HUD = MBProgressHUD.showAdded(to: supview
, animated: true)
HUD.frame = CGRect(x: 0, y: 0, width: EWScreenInfo.Width, height: EWScreenInfo.Height)
HUD.animationType = .zoom
if isMask {
/// 蒙层type,背景半透明.
HUD.backgroundView.color = UIColor(white: 0.0, alpha: 0.4)
} else {
/// 非蒙层type,没有背景.
HUD.backgroundView.color = UIColor.clear
HUD.bezelView.backgroundColor = UIColor(white: 0.0, alpha: 0.9)
HUD.contentColor = UIColor.white
}
HUD.removeFromSuperViewOnHide = true
HUD.show(animated: true)
return HUD
}
2.实现显示HUD方法.
/// 直接展示Hud
///
/// - Parameters:
/// - message: 显示信息
/// - icon: 显示图片
/// - view: 加载到哪个View上展示
/// - coverNavigationController: 要覆盖NavigationBar,需要传入NavigationController
/// - isTranslucent: 自己项目中navigationBar是否参与frame设置,默认为False,如果项目中主动将其设置为true,可以传入True.不传的话中弹出view会有半个navigationBar.height的向下偏移.
/// - completeBlock: UD消失后调用block
private class func showHudTips (message : String?, icon : String?, view : UIView?, coverNavigationController: UINavigationController? = nil, isTranslucent: Bool = false,completeBlock : (()->(Void))?) {
var HUD: MBProgressHUD?
if coverNavigationController != nil {
HUD = self.createHud(navigationController: coverNavigationController!)
}else {
HUD = self.createHud(view: view, isMask: false, isTranslucent: isTranslucent)
}
HUD?.label.text = message
HUD?.label.numberOfLines = 0
/// 如果有Icon展示.
if let icon = icon {
HUD?.customView = UIImageView.init(image: UIImage.init(named: "\(icon)"))
}
HUD?.mode = .customView
/// 在hud消失时调用completeBlock.
DispatchQueue.main.asyncAfter(deadline: .now() + hudShowTime) {
HUD?.hide(animated: true)
guard let completeBlock = completeBlock else {
return
}
completeBlock()
}
}
3.展示loadingView方法.
两个方法,返回实例方法可以根据自己需求修改返回的实例.
调用展示loadingView时,必须在结束loading时手动调用隐藏HUD方法!!!
/// 展示loadingHUD,可用于网络请求
///
/// - Parameters:
/// - view: 父级View,默认是当前展示View
/// - message: 展示文字
/// - isMask: 是否是蒙层形式,true是半透明背景的蒙层模式,false是只有Hub不带背景
/// - isTranslucent: 自己项目中navigationBar是否参与frame设置,默认为False,如果项目中主动将其设置为true,可以传入True.不传的话中弹出view会有半个navigationBar.height的向下偏移.
class func showLoadingHudView (view : UIView? = UIApplication.shared.keyWindow ,message:String?, isMask : Bool = false,isTranslucent: Bool = false){
let HUD = self.createHud(view: view,isMask: isMask, isTranslucent: isTranslucent)
HUD?.mode = .indeterminate
HUD?.label.text = message
hud = HUD
}
/// 展示loadingHUD,可用于网络请求
///
/// - Parameters:
/// - NAVC: 要覆盖NavigationBar,需要传入NavigationController
/// - message: 展示文字
/// - isMask: 是否是蒙层形式,true是半透明背景的蒙层模式,false是只有Hub不带背景
class func showLoadingHudView (NAVC : UINavigationController? ,message:String?){
let HUD = self.createHud(navigationController: NAVC, isMask: true)
HUD?.mode = .indeterminate
HUD?.label.text = message
hud = HUD
}
/// 生成实例的loadingHUD,可以再对实例进行自定义修改
///
/// - Parameters:
/// - view: 父级View,默认是当前展示View
/// - message: 展示文字
/// - isMask: 是否是蒙层形式,true是半透明背景的蒙层模式,false是只有Hub不带背景
/// - isTranslucent: 自己项目中navigationBar是否参与frame设置,默认为False,如果项目中主动将其设置为true,可以传入True.不传的话中弹出view会有半个navigationBar.height的向下偏移.
/// - Returns: hud示例,可以自己为实例进行修改
class func showLoadingHudInView (view : UIView? = UIApplication.shared.keyWindow ,message:String?, isMask : Bool = false,isTranslucent: Bool = false) -> MBProgressHUD?{
let HUD = self.createHud(view: view, isMask: isMask, isTranslucent: isTranslucent)
HUD?.mode = .indeterminate
HUD?.label.text = message
hud = HUD
return hud
}
4.类Toast只展示文字方法.
/// 展示类ToastHUD
///
/// - Parameters:
/// - message: 展示文字
/// - view: 父级View,默认是当前展示View
/// - isMask: 是否是蒙层形式,true是半透明背景的蒙层模式,false是只有Hub不带背景
/// - afterDelay: view消失时间
/// - isTranslucent: 自己项目中navigationBar是否参与frame设置,默认为False,如果项目中主动将其设置为true,可以传入True.不传的话中弹出view会有半个navigationBar.height的向下偏移.
class func showTextHudTips(message : String?, view : UIView? = UIApplication.shared.keyWindow , isMask : Bool = false,afterDelay:Double = hudShowTime,isTranslucent: Bool = false) {
let HUD = self.createHud(view: view, isMask: isMask, isTranslucent: isTranslucent)
HUD?.mode = .text
HUD?.detailsLabel.font = UIFont.systemFont(ofSize: 16.0)
HUD?.detailsLabel.text = message
HUD?.hide(animated: true, afterDelay: afterDelay)
}
/// 覆盖NavigationBar的l类ToastHUD
///
/// - Parameters:
/// - NAVC: 要覆盖NavigationBar,需要传入NavigationController
/// - message: 展示文字
/// - isMask: 是否是蒙层形式,true是半透明背景的蒙层模式,false是只有Hub不带背景
/// - afterDelay: view消失时间
class func showTextHudTips(NAVC : UINavigationController? ,message:String?, isMask : Bool = false,afterDelay: Double = hudShowTime){
let HUD = self.createHud(navigationController: NAVC,isMask :isMask)
HUD?.mode = .text
HUD?.detailsLabel.font = UIFont.systemFont(ofSize: 16.0)
HUD?.detailsLabel.text = message
HUD?.hide(animated: true, afterDelay: afterDelay)
}
/// 生成实例的类ToastHUD,可以再对实例进行自定义修改
///
/// - Parameters:
/// - message: 展示文字
/// - view: 父级View,默认是当前展示View
/// - isMask: 是否是蒙层形式,true是半透明背景的蒙层模式,false是只有Hub不带背景
/// - afterDelay: view消失时间
/// - isTranslucent: 自己项目中navigationBar是否参与frame设置,默认为False,如果项目中主动将其设置为true,可以传入True.不传的话中弹出view会有半个navigationBar.height的向下偏移.
/// - Returns: hud示例,可以自己为实例进行修改
class func showTextHud (message : String?, view : UIView? = UIApplication.shared.keyWindow , isMask : Bool = false,afterDelay:Double = hudShowTime,isTranslucent: Bool = false) -> MBProgressHUD? {
let HUD = self.createHud(view: view, isMask: isMask, isTranslucent: isTranslucent)
HUD?.mode = .text
HUD?.detailsLabel.font = UIFont.systemFont(ofSize: 16.0)
HUD?.detailsLabel.text = message
HUD?.hide(animated: true, afterDelay: afterDelay)
return HUD
}
5.展示成功,失败类似icon+文字方法.
本质上是icon+文字形式,传入自己项目图片,建议大小为64X64
// 展示成功HUD,可自己修改图片,icon图片需要自己添加到项目中,建议大小为64X64
///
/// - Parameters:
/// - message: 展示文字
/// - view: 父级View,默认是当前展示View
/// - afterDelay: view消失时间
/// - isTranslucent: 自己项目中navigationBar是否参与frame设置,默认为False,如果项目中主动将其设置为true,可以传入True.不传的话中弹出view会有半个navigationBar.height的向下偏移.
class func showSuccesshTips (message : String?, view : UIView? = UIApplication.shared.keyWindow ,afterDelay:Double = hudShowTime,isTranslucent: Bool = false) {
self.showHudTips(message: message, icon: "Success.png", view: view, isTranslucent: isTranslucent, completeBlock: nil)
}
// 展示成功HUD,可传入HUD隐藏后调用Block
///
/// - Parameters:
/// - message: 展示文字
/// - view: 父级View,默认是当前展示View
/// - isTranslucent: 自己项目中navigationBar是否参与frame设置,默认为False,如果项目中主动将其设置为true,可以传入True.不传的话中弹出view会有半个navigationBar.height的向下偏移.
/// - completeBlock: 成功回调,在view隐藏后会执行回调
class func showSuccesshTips (message : String?, view : UIView? = UIApplication.shared.keyWindow ,isTranslucent: Bool = false, completeBlock : (()->(Void))?) {
self.showHudTips(message: message, icon: "success.png", view: view, isTranslucent: isTranslucent, completeBlock: completeBlock)
}
// 展示失败HUD,可自己修改图片,icon图片需要自己添加到项目中,建议大小为64X64
///
/// - Parameters:
/// - message: 展示文字
/// - view: 父级View,默认是当前展示View
/// - isTranslucent: 自己项目中navigationBar是否参与frame设置,默认为False,如果项目中主动将其设置为true,可以传入True.不传的话中弹出view会有半个navigationBar.height的向下偏移.
class func showErrorMessage(message : String?, view : UIView? = UIApplication.shared.keyWindow,isTranslucent: Bool = false){
self.showHudTips(message: message, icon: "error.png", view: view, isTranslucent: isTranslucent, completeBlock: nil)
}
// 展示失败HUD,可传入HUD隐藏后调用Block
///
/// - Parameters:
/// - message: 展示文字
/// - view: 父级View,默认是当前展示View
/// - isTranslucent: 自己项目中navigationBar是否参与frame设置,默认为False,如果项目中主动将其设置为true,可以传入True.不传的话中弹出view会有半个navigationBar.height的向下偏移.
/// - completeBlock: 成功回调,在view隐藏后会执行回调
class func showErrorMessage (message : String?, view : UIView? = UIApplication.shared.keyWindow,isTranslucent: Bool = false, completeBlock : (()->(Void))?) {
self.showHudTips(message: message, icon: "error.png", view: view, isTranslucent: isTranslucent, completeBlock: nil)
}
6.隐藏HUD方法
/// 隐藏HUD
class func hideHud () {
guard let HUD = hud else {
return
}
HUD.hide(animated: true)
hud = nil
}
使用方法示例:
1.使用CocoaPods或手动将MBProgressHUD加入项目.
2.将EWMBProgressHUD.swift文件加入项目.
3.调用时:
@objc private func onClickTopButton(){
EWMBProgressHud.showTextHudTips(message: "蒙层", view: self.view, isMask: true, afterDelay: 1)
}
@objc private func onClickCenterButton(){
EWMBProgressHud.showTextHudTips(message: "Toast", isTranslucent: true)
}
@objc private func onClickLoadingButton(){
EWMBProgressHud.showLoadingHudView(message: "Loading", isTranslucent: true)
/// loadingView必需手动隐藏!!!结束loading请调用hideHud()!!!
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1) {
EWMBProgressHud.hideHud()
}
}
@objc private func onClickSecondLoadingButton(){
EWMBProgressHud.showLoadingHudView(view: self.view, message: "蒙层Loading", isMask: true)
/// loadingView必需手动隐藏!!!结束loading请调用hideHud()!!!
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1) {
EWMBProgressHud.hideHud()
}
}
@objc private func onClickSuccessButton(){
EWMBProgressHud.showSuccesshTips(message: "Success",afterDelay: 1, isTranslucent: true)
}
@objc private func onClickCoverNavigationBarLoadingButton(){
/// 覆盖navigationBar需要从NavitionController中添加View,所以需要传入navigationController
EWMBProgressHud.showLoadingHudView(NAVC: self.navigationController, message: "覆盖NavigationBar的LoadingView")
/// loadingView必需手动隐藏!!!结束loading请调用hideHud()!!!
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1) {
EWMBProgressHud.hideHud()
}
}
@objc private func onClicKCoverNavigationBarButton(){
EWMBProgressHud.showTextHudTips(NAVC: self.navigationController, message: "覆盖NavigationBar的蒙层", isMask: true,afterDelay: 1)
}
demo地址:EWMBProgressHUD
有问题欢迎探讨.