168 lines
4.1 KiB
Swift
168 lines
4.1 KiB
Swift
//
|
||
// YMRequestLoadingPlugin.swift
|
||
// yinmeng-ios
|
||
//
|
||
// Created by MaiMang on 2024/2/2.
|
||
//
|
||
|
||
import Foundation
|
||
import Moya
|
||
import MBProgressHUD
|
||
|
||
/// 加载插件,基于MBProgressHUD封装
|
||
/// Loading plugin, based on MBProgressHUD package
|
||
public struct YMRequestLoadingPlugin: PluginPropertiesable {
|
||
|
||
public var plugins: APIPlugins = []
|
||
|
||
public var key: String?
|
||
|
||
public var delay: Double {
|
||
options.delayHideHUD
|
||
}
|
||
|
||
public var options: Options
|
||
|
||
public init(options: Options = .init()) {
|
||
self.options = options
|
||
}
|
||
|
||
/// Hide the loading hud.
|
||
public func hideMBProgressHUD() {
|
||
let vc = YMRequestX.removeHUD(key: key)
|
||
vc?.close()
|
||
}
|
||
}
|
||
|
||
extension YMRequestLoadingPlugin {
|
||
public struct Options {
|
||
/// Loading will not be automatically hidden and display window.
|
||
public static let dontAutoHide: Options = .init(autoHide: false)
|
||
|
||
/// Do you need to display an error message, the default is empty
|
||
let displayLoadText: String
|
||
/// Delay hidden, the default is zero seconds
|
||
let delayHideHUD: Double
|
||
/// Do you need to automatically hide the loading hud.
|
||
let autoHideLoading: Bool
|
||
|
||
public init(text: String = "", delay: Double = 0.0, autoHide: Bool = true) {
|
||
self.displayLoadText = text
|
||
self.delayHideHUD = delay
|
||
self.autoHideLoading = autoHide
|
||
}
|
||
|
||
var hudCallback: ((_ hud: MBProgressHUD) -> Void)?
|
||
|
||
/// Change hud related configuration closures.
|
||
public mutating func setChangeHudParameters(block: @escaping (_ hud: MBProgressHUD) -> Void) {
|
||
self.hudCallback = block
|
||
}
|
||
}
|
||
}
|
||
|
||
extension YMRequestLoadingPlugin: PluginSubType {
|
||
|
||
public var pluginName: String {
|
||
return "Loading"
|
||
}
|
||
|
||
public func willSend(_ request: RequestType, target: TargetType) {
|
||
DispatchQueue.main.async {
|
||
self.showText(options.displayLoadText)
|
||
}
|
||
}
|
||
|
||
public func didReceive(_ result: Result<Moya.Response, MoyaError>, target: TargetType) {
|
||
if options.autoHideLoading == false, case .success = result {
|
||
return
|
||
}
|
||
DispatchQueue.main.asyncAfter(deadline: .now() + options.delayHideHUD) {
|
||
self.hideMBProgressHUD()
|
||
}
|
||
}
|
||
}
|
||
|
||
extension YMRequestLoadingPlugin {
|
||
|
||
/// Display the prompt text
|
||
private func showText(_ text: String) {
|
||
guard let key = self.key else {
|
||
return
|
||
}
|
||
if let vc = YMRequestX.readHUD(key: key) {
|
||
if let _ = MBProgressHUD.forView(vc.view) {
|
||
return
|
||
}
|
||
vc.show()
|
||
} else {
|
||
let vc = LevelStatusBarWindowController()
|
||
|
||
// Set Activity Indicator View to white for hud loading.
|
||
let indicatorView = UIActivityIndicatorView.appearance(whenContainedInInstancesOf: [MBProgressHUD.self])
|
||
indicatorView.color = UIColor.white
|
||
|
||
let hud = MBProgressHUD.showAdded(to: vc.view, animated: true)
|
||
hud.mode = MBProgressHUDMode.indeterminate
|
||
hud.animationType = MBProgressHUDAnimation.zoom
|
||
hud.removeFromSuperViewOnHide = true
|
||
hud.bezelView.style = MBProgressHUDBackgroundStyle.solidColor
|
||
hud.bezelView.color = UIColor.black.withAlphaComponent(0.7)
|
||
hud.bezelView.layer.cornerRadius = 14
|
||
hud.detailsLabel.text = text
|
||
hud.detailsLabel.font = UIFont.systemFont(ofSize: 16)
|
||
hud.detailsLabel.numberOfLines = 0
|
||
hud.detailsLabel.textColor = UIColor.white
|
||
|
||
// User defined the hud configuration.
|
||
self.options.hudCallback?(hud)
|
||
|
||
vc.key = key
|
||
vc.showUpView = hud
|
||
vc.addedShowUpView = true
|
||
vc.show()
|
||
YMRequestX.saveHUD(key: key, window: vc)
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
extension MBProgressHUD: LevelStatusBarWindowShowUpable {
|
||
|
||
public func makeOpenedStatusConstraint(superview: UIView) {
|
||
|
||
}
|
||
|
||
public func refreshBeforeShow() {
|
||
|
||
}
|
||
|
||
public func show(animated: Bool, animation: (() -> Void)?, completion: ((Bool) -> Void)?) {
|
||
DispatchQueue.main.async {
|
||
self.show(animated: animated)
|
||
if animated {
|
||
UIView.animate(withDuration: 0.2, animations: {
|
||
animation?()
|
||
}, completion: completion)
|
||
} else {
|
||
animation?()
|
||
completion?(true)
|
||
}
|
||
}
|
||
}
|
||
|
||
public func close(animated: Bool, animation: (() -> Void)?, completion: ((Bool) -> Void)?) {
|
||
DispatchQueue.main.async {
|
||
self.hide(animated: animated)
|
||
if animated {
|
||
UIView.animate(withDuration: 0.2, animations: {
|
||
animation?()
|
||
}, completion: completion)
|
||
} else {
|
||
animation?()
|
||
completion?(true)
|
||
}
|
||
}
|
||
}
|
||
}
|