jsdw_ios/QuickLocation/UIKit/HUD/ProgressHUD.swift

216 lines
9.2 KiB
Swift

//
// 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)
}
}