// // ProgressHUD.swift // JiuLaiBao // // Created by 霹雳火 on 2018/8/15. // Copyright © 2018 GuoXiaoMei. All rights reserved. // import UIKit import MBProgressHUD public class ProgressHUD: NSObject { public enum HUDType { case loading(status: String?) case progress(progress: Float, status: String?) case info(status: String?) case success(status: String?) case error(status: String?) case dismiss case dismissImmediate case dismissDelay(delay: TimeInterval) case dismissDelayAndCompletion(delay: TimeInterval, completion: ProgressHUD.ProgressHUDDismissCompletion?) case dismissCompletion(completion: ProgressHUD.ProgressHUDDismissCompletion?) } public typealias ProgressHUDDismissCompletion = (() -> Void) static public var successImage = UIImage(named: "ProgressHUD/success")! static public var errorImage = UIImage(named: "ProgressHUD/error")! static public var infoImage = UIImage(named: "ProgressHUD/info")! static public let ProgressHUDUndefinedProgress: Float = -1 static public var minimumDismissTimeInterval: TimeInterval = 1 static public var maximumDismissTimeInterval: TimeInterval = 3 static public func createProgressHUD(for view: UIView) -> MBProgressHUD { let hud = MBProgressHUD.showAdded(to: view, animated: true) hud.contentColor = .white hud.animationType = .fade hud.removeFromSuperViewOnHide = true hud.isUserInteractionEnabled = true hud.bezelView.color = UIColor.black.withAlphaComponent(0.53) hud.bezelView.style = .solidColor hud.label.numberOfLines = 0 hud.detailsLabel.font = UIFont.boldSystemFont(ofSize: 16) return hud } static public func findProgressHUD(for view: UIView) -> MBProgressHUD? { let hud = MBProgressHUD(view: view) hud.isUserInteractionEnabled = true return hud } static public func frontWindow() -> UIWindow { let mainWindow = UIApplication.shared.delegate?.window return mainWindow!! } // MARK: show/hide method @discardableResult static public func show(withStatus status: String? = nil, addedTo view: UIView? = nil) -> MBProgressHUD { return showProgress(progress: ProgressHUDUndefinedProgress, status: status, addedTo: view) } @discardableResult static public func showProgress(progress: Float, status: String? = nil, addedTo view: UIView? = nil, offset: CGPoint = .zero) -> MBProgressHUD { let hudView: MBProgressHUD let forView = view ?? frontWindow() if let findHUD = findProgressHUD(for: forView) { hudView = findHUD } else { hudView = createProgressHUD(for: forView) } if progress == ProgressHUDUndefinedProgress { hudView.mode = .indeterminate } else { hudView.mode = .annularDeterminate hudView.progress = progress } hudView.detailsLabel.text = status hudView.isUserInteractionEnabled = true hudView.offset = offset forView.bringSubviewToFront(hudView) return hudView } @discardableResult static public func show(_ image: UIImage, status: String? = nil, addedTo view: UIView? = nil, offset: CGPoint = .zero) -> MBProgressHUD { let displayInterval = displayDuration(for: status) let hudView: MBProgressHUD let forView = view ?? frontWindow() if let findHUD = findProgressHUD(for: forView) { hudView = findHUD } else { hudView = createProgressHUD(for: forView) } hudView.mode = .customView hudView.customView = UIImageView(image: image) hudView.detailsLabel.text = status hudView.offset = offset hudView.isUserInteractionEnabled = false forView.bringSubviewToFront(hudView) hudView.hide(animated: true, afterDelay: displayInterval) return hudView } // MARK: show/hide method @discardableResult static public func show(withStatus status: String? = nil, inController controller: UIViewController?) -> MBProgressHUD { return showProgress(progress: ProgressHUDUndefinedProgress, status: status, inController: controller) } @discardableResult static public func showProgress(progress: Float, status: String? = nil, inController controller: UIViewController?) -> MBProgressHUD { if let controller = controller { if controller.fd_prefersNavigationBarHidden { return showProgress(progress: progress, status: status, addedTo: controller.view) } else { let navigatorHeight = UIApplication.shared.statusBarFrame.size.height + 44.0 let offset = CGPoint(x: 0, y: -navigatorHeight / 2.0) return showProgress(progress: progress, status: status, addedTo: controller.view, offset: offset) } } else { return showProgress(progress: progress, status: status, addedTo: nil) } } @discardableResult static public func showInfo(withStatus status: String? = nil, addedTo view: UIView? = nil) -> MBProgressHUD { return show(infoImage, status: status, addedTo: view) } @discardableResult static public func showSuccess(withStatus status: String? = nil, addedTo view: UIView? = nil) -> MBProgressHUD { return show(successImage, status: status, addedTo: view) } @discardableResult static public func showError(withStatus status: String? = nil, addedTo view: UIView? = nil) -> MBProgressHUD { return show(errorImage, status: status, addedTo: view) } @discardableResult static public func showInfo(withStatus status: String? = nil, inController controller: UIViewController?) -> MBProgressHUD { return show(infoImage, status: status, inController: controller) } @discardableResult static public func showSuccess(withStatus status: String? = nil, inController controller: UIViewController?) -> MBProgressHUD { return show(successImage, status: status, inController: controller) } @discardableResult static public func showError(withStatus status: String? = nil, inController controller: UIViewController?) -> MBProgressHUD { return show(errorImage, status: status, inController: controller) } @discardableResult static public func show(_ image: UIImage, status: String? = nil, inController controller: UIViewController?) -> MBProgressHUD { if let controller = controller { if controller.fd_prefersNavigationBarHidden { return show(image, status: status, addedTo: controller.view) } else { let navigatorHeight = UIApplication.shared.statusBarFrame.size.height + 44.0 let offset = CGPoint(x: 0, y: -navigatorHeight / 2.0) return show(image, status: status, addedTo: controller.view, offset: offset) } } else { return show(image, status: status, addedTo: controller?.view) } } static public func dismiss(withDelay delay: TimeInterval = 0, immediate: Bool = false, forView view: UIView? = nil, completion: ProgressHUDDismissCompletion? = nil) { let forView = view ?? frontWindow() let hudView = findProgressHUD(for: forView) hudView?.completionBlock = completion if immediate { hudView?.hide(animated: false) } else { hudView?.hide(animated: true, afterDelay: delay) } } static public func dismiss(withDelay delay: TimeInterval = 0, immediate: Bool = false, forController controller: UIViewController?, completion: ProgressHUDDismissCompletion? = nil) { let forView = controller?.view ?? frontWindow() let hudView = findProgressHUD(for: forView) hudView?.completionBlock = completion if immediate { hudView?.hide(animated: false) } else { hudView?.hide(animated: true, afterDelay: delay) } } static public func displayDuration(for string: String?) -> TimeInterval { let minimum = Double.maximum(Double(string?.count ?? 0) * 0.06 + 0.5, minimumDismissTimeInterval) return Double.minimum(minimum, maximumDismissTimeInterval) } }