wjtx-client-ios/ios-template/common/ZLoadingView.swift
2021-07-22 16:13:00 +08:00

300 lines
9.5 KiB
Swift

//
// ZLoadingView.swift
//
//
// Created by zhl on 2021/7/22.
// Copyright © 2021 egret. All rights reserved.
//
import UIKit
/// Creates and returns a color object using the specified opacity and RGB component values.
///
/// - Parameters:
/// - r: The red value of the color object, specified as a value from 0.0 to 255.0.
/// - g: The green value of the color object, specified as a value from 0.0 to 255.0.
/// - b: The blue value of the color object, specified as a value from 0.0 to 255.0.
/// - alp: The opacity value of the color object, specified as a value from 0.0 to 1.0.
/// - Returns: The color object. The color information represented by this object is in an RGB colorspace.
public func COLOR_RGBA(_ r: CGFloat,
_ g: CGFloat,
_ b: CGFloat,
_ alp: CGFloat) -> UIColor {
return UIColor(red: r/255.0, green: g/255.0, blue: b/255.0, alpha: alp)
}
/// Creates and returns a color object using the specified opacity and RGB component values.
///
/// - Parameters:
/// - r: The red value of the color object, specified as a value from 0.0 to 255.0.
/// - g: The green value of the color object, specified as a value from 0.0 to 255.0.
/// - b: The blue value of the color object, specified as a value from 0.0 to 255.0.
/// - Returns: The color object. The color information represented by this object is in an RGB colorspace.
public func COLOR_RGB(_ r: CGFloat,
_ g: CGFloat,
_ b: CGFloat) -> UIColor {
return COLOR_RGBA(r, g, b, 1.0)
}
/// Returns the width of the screen for the device.
public let SCREEN_W = UIScreen.main.bounds.size.width
/// Returns the height of the screen for the device.
public let SCREEN_H = UIScreen.main.bounds.size.height
public class ZLoadingView: UIView {
/// It is used to act as background mask panel.
private lazy var maskPanel: UIView = {
let view = UIView()
view.backgroundColor = COLOR_RGBA(20, 20, 20, 0.5)
return view
}()
/// It is used to render the content.
private lazy var contentView: UIView = {
let view = UIView()
view.backgroundColor = COLOR_RGB(255, 255, 255)
return view
}()
/// The spinner is used to provide an indefinite animation.
private lazy var indicator: ZIndefiniteAnimatedSpinner = {
let spinner = ZIndefiniteAnimatedSpinner()
spinner.backgroundColor = UIColor.clear
spinner.lineColor = COLOR_RGB(100, 100, 100)
return spinner
}()
/// It is used to show the text.
private lazy var textLabel: UILabel = {
let label = UILabel()
label.backgroundColor = UIColor.clear
label.textColor = COLOR_RGB(60, 60, 60)
return label
}()
/// Returns the current window of the app.
private func appWindow() -> UIWindow {
let sharedApp = UIApplication.shared
return sharedApp.keyWindow ?? sharedApp.windows[0]
}
/// The color to set the background color of the content view.
public var color: UIColor? {
get {
return self.contentView.backgroundColor
}
set {
self.contentView.backgroundColor = newValue
}
}
/// The color to set the line color of the indicator.
public var indicatorColor: UIColor? {
get {
return self.indicator.lineColor
}
set {
self.indicator.lineColor = newValue
}
}
/// The color to set the text color of the text label.
public var textColor: UIColor? {
get {
return self.textLabel.textColor
}
set (newColor) {
self.textLabel.textColor = newColor
}
}
/// Initializes and returns a newly allocated view object with the specified frame rectangle.
/// - Parameter frame: The frame rectangle for the view.
public override init(frame: CGRect) {
super.init(frame: frame)
}
/// Returns an object initialized from data in a given unarchiver.
/// - Parameter coder: An unarchiver object.
public required init?(coder: NSCoder) {
super.init(coder: coder)
}
public override func awakeFromNib() {
// Prepares the receiver for service after it has been loaded
// from an Interface Builder archive, or nib file.
}
/// It will be displayed on the screen with the text.
/// - Parameter text: The text to prompt the user.
public func show(_ text: String) {
self.configure(text)
self.loadView()
self.beginAnimating()
}
/// Configures properties for the widget used.
private func configure(_ text: String) {
self.autoresizingMask = UIView.AutoresizingMask(rawValue: UIView.AutoresizingMask.flexibleLeftMargin.rawValue |
UIView.AutoresizingMask.flexibleTopMargin.rawValue |
UIView.AutoresizingMask.flexibleWidth.rawValue |
UIView.AutoresizingMask.flexibleHeight.rawValue
)
self.maskPanel.autoresizingMask = UIView.AutoresizingMask(rawValue: UIView.AutoresizingMask.flexibleLeftMargin.rawValue |
UIView.AutoresizingMask.flexibleTopMargin.rawValue |
UIView.AutoresizingMask.flexibleWidth.rawValue |
UIView.AutoresizingMask.flexibleHeight.rawValue
)
let cw = 200.0
self.contentView.frame = CGRect(x: 0, y: 0, width: cw, height: 0.6*cw)
self.contentView.setCorner(radius: 10.0)
let offset = 10.0
let iw = 60.0
let ix = cw/2 - iw/2
let iy = 1.5*offset
self.indicator.frame = CGRect(x: ix, y: iy, width: iw, height: iw)
self.indicator.lineWidth = 2.0
let lh = 20.0
self.textLabel.center = CGPoint(x: cw/2, y: 0.6*cw - lh/2 - 1.5*offset)
self.textLabel.bounds = CGRect(x: 0, y: 0, width: cw - 2*offset, height: lh)
self.textLabel.text = text
self.textLabel.font = UIFont.boldSystemFont(ofSize: 16.0)
self.textLabel.textAlignment = NSTextAlignment.center
self.textLabel.numberOfLines = 1
}
/// Addds the subviews to its corresponding superview.
private func loadView() {
if let vc = self.appCurrentViewController() {
vc.view.addSubview(self)
vc.view.bringSubviewToFront(self)
} else {
let window = self.appWindow()
window.addSubview(self)
window.bringSubviewToFront(self)
}
self.addSubview(self.maskPanel)
self.addSubview(self.contentView)
self.bringSubviewToFront(self.contentView)
self.contentView.addSubview(self.indicator)
self.contentView.addSubview(self.textLabel)
}
/// Prepares to begin animating.
private func beginAnimating() {
self.indicator.startAnimating()
self.alpha = 0.0
UIView.animate(withDuration: 0.3) {
self.alpha = 1.0
}
}
/// Hides from its own superview.
public func hide() {
let opts = UIView.AnimationOptions.curveEaseInOut
UIView.animate(withDuration: 0.3, delay: 1.0, options: opts, animations: {
self.alpha = 0.0
}) { (finished) in
self.indicator.stopAnimating()
self.removeAllViews()
}
}
/// Removes all views at the end of the hidden animation.
private func removeAllViews() {
for view in self.subviews {
view.removeFromSuperview()
}
self.removeFromSuperview()
}
/// Finds out the current view controller.
private func appCurrentViewController() -> UIViewController? {
guard var vc = self.appWindow().rootViewController else {
return nil
}
while true {
if let tvc = vc.presentedViewController {
vc = tvc
} else if vc.isKind(of: UITabBarController.self) {
let tbc = vc as! UITabBarController
if let tvc = tbc.selectedViewController {
vc = tvc
}
} else if vc.isKind(of: UINavigationController.self) {
let nc = vc as! UINavigationController
if let tvc = nc.visibleViewController {
vc = tvc
}
} else {
if vc.children.count > 0 {
if let tvc = vc.children.last {
vc = tvc
}
}
break
}
}
return vc
}
public override func layoutSubviews() {
var self_w: CGFloat = 0.0
var self_h: CGFloat = 0.0
if let supv = self.superview {
self_w = supv.bounds.size.width
self_h = supv.bounds.size.height
} else {
self_w = SCREEN_W
self_h = SCREEN_H
}
self.frame = CGRect(x: 0, y: 0, width: self_w, height: self_h)
self.maskPanel.frame = CGRect(x: 0, y: 0, width: self_w, height: self_h)
self.contentView.center = CGPoint(x: self_w/2, y: self_h/2)
}
deinit {
#if DEBUG
print("[\((#file as NSString).lastPathComponent):\(#function)]")
#endif
}
}