This commit is contained in:
xaoxuu 2019-08-03 16:22:50 +08:00
parent 1da5242844
commit 3639558a9c
17 changed files with 639 additions and 197 deletions

View File

@ -6,7 +6,7 @@
}, },
{ {
"idiom" : "universal", "idiom" : "universal",
"filename" : "IMG_0564.PNG", "filename" : "IMG_099256E14955-1.jpeg",
"scale" : "2x" "scale" : "2x"
}, },
{ {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 530 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

View File

@ -19,6 +19,14 @@
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" image="bg" translatesAutoresizingMaskIntoConstraints="NO" id="0oA-CL-uZS"> <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" image="bg" translatesAutoresizingMaskIntoConstraints="NO" id="0oA-CL-uZS">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/> <rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
</imageView> </imageView>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="PcH-Px-Vql">
<rect key="frame" x="51" y="120" width="46" height="30"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<state key="normal" title="Button"/>
<connections>
<action selector="test:" destination="BYZ-38-t0r" eventType="touchUpInside" id="mff-h5-exz"/>
</connections>
</button>
</subviews> </subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints> <constraints>

View File

@ -17,27 +17,77 @@ class ViewController: UIViewController {
ProHUD.configAlert { (alert) in ProHUD.configAlert { (alert) in
alert.minimizeTimeout = 5 alert.minimizeTimeout = 3
} }
ProHUD.configGuard { (g) in
g.tintColor = .success
}
ProHUD.configToast { (toast) in
// toast.backgroundColorForScene { (scene) -> UIColor? in
// return UIColor.yellow
// }
}
} }
func testToast() {
let t = ProHUD.Toast(scene: .loading, title: "正在加载", message: "请稍候片刻")
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let a = ProHUD.show(alert : .loading, title: "正在加载", message: "请稍候片刻")
a.didMinimize {
hud.show(t)
}
t.didTapped { [weak t] in
t?.remove()
let a2 = ProHUD.show(alert: .loading, title: "正在加载", message: "马上就要成功了")
DispatchQueue.main.asyncAfter(deadline: .now()+1) {
let a3 = ProHUD.show(alert: .error, title: "加载失败", message: "点击充实")
a3.addAction(style: .default, title: "重新加载") { [weak a3] in
a3?.updateContent(scene: .success, title: "加载成功", message: "马上就要成功了")
a3?.updateAction(index: 0, style: .default, title: "OK", action: { [weak a2, a3] in
a2?.remove()
a3?.remove()
}).removeAction(index: 1).removeAction(index: 1)
}.addAction(style: .destructive, title: "终止", action: nil).addAction(style: .cancel, title: "取消", action: nil)
}
}
}
func testDelete() {
let a = ProHUD.show(alert: .delete, title: "确认删除", message: "此操作不可撤销") let a = ProHUD.show(alert: .delete, title: "确认删除", message: "此操作不可撤销")
a.addAction(style: .destructive, title: "确认", action: { [weak a] in a.addAction(style: .destructive, title: "确认", action: { [weak a] in
a?.removeAction(index: 0).removeAction(index: 0) a?.removeAction(index: 0).removeAction(index: 0)
a?.updateContent(scene: .loading, title: "正在删除", message: "请稍后片刻") a?.updateContent(scene: .loading, title: "正在删除", message: "请稍后片刻")
DispatchQueue.main.asyncAfter(deadline: .now()+1) { DispatchQueue.main.asyncAfter(deadline: .now()+1) {
a?.updateContent(scene: .success, title: "删除成功", message: "啊哈哈哈哈").timeout(2) a?.updateContent(scene: .success, title: "删除成功", message: "啊哈哈哈哈").timeout(2)
a?.addAction(style: .default, title: "我知道了", action: { ProHUD.show(toast: .success, title: "删除成功", message: "aaa")
// a?.remove()
a?.removeAction(index: 0)
})
} }
}).addAction(style: .cancel, title: "取消", action: nil) }).addAction(style: .cancel, title: "取消", action: nil)
}
@IBAction func test(_ sender: UIButton) {
let g = ProHUD.Guard(title: "请求权限", message: "请打开相机权限开关,否则无法进行测量。")
// g.view.tintColor = .warning
// g.loadBody(g.description)
g.loadButton(style: .default, title: "测试弹窗", action: { [weak self] in
self?.testToast()
})
g.loadButton(style: .destructive, title: "测试删除弹窗", action: { [weak self] in
self?.testDelete()
})
g.loadButton(style: .cancel, title: "我知道了")
g.push(to: self)
debugPrint("test: ", g)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
// //
// ProHUD.show(alert: .loading, title: "", message: "").timeout(nil) // ProHUD.show(alert: .loading, title: "", message: "").timeout(nil)
@ -63,28 +113,7 @@ class ViewController: UIViewController {
// //
// } // }
// let t = ProHUD.Toast(scene: .loading, title: "", message: "")
//
// let a = ProHUD.show(alert : .loading, title: "", message: "")
// a.didMinimize {
// hud.show(t)
// }
// t.didTapped { [weak t] in
// t?.remove()
// let a2 = ProHUD.show(alert: .loading, title: "", message: "")
// DispatchQueue.main.asyncAfter(deadline: .now()+1) {
// let a3 = ProHUD.show(alert: .error, title: "", message: "")
// a3.addAction(style: .default, title: "") { [weak a3] in
// a3?.updateContent(scene: .success, title: "", message: "")
// a3?.updateAction(index: 0, style: .default, title: "OK", action: { [weak a2, a3] in
// a2?.remove()
// a3?.remove()
// }).removeAction(index: 1).removeAction(index: 1)
// }.addAction(style: .destructive, title: "", action: nil).addAction(style: .cancel, title: "", action: nil)
//
// }
//
// }
// ProHUD.show(toast: .loading, title: "", message: "") // ProHUD.show(toast: .loading, title: "", message: "")

View File

@ -31,7 +31,7 @@ public extension ProHUD.Configuration {
/// ///
public var titleFont = UIFont.boldSystemFont(ofSize: 22) public var titleFont = UIFont.boldSystemFont(ofSize: 22)
/// ///
public var titleColor = UIColor(white: 0.2, alpha: 1) public var titleColor = UIColorForPrimaryLabel
/// ///
public var titleMaxLines = Int(1) public var titleMaxLines = Int(1)
@ -41,7 +41,7 @@ public extension ProHUD.Configuration {
/// ///
public var bodyFont = UIFont.systemFont(ofSize: 17) public var bodyFont = UIFont.systemFont(ofSize: 17)
/// ///
public var bodyColor = UIColor.darkGray public var bodyColor = UIColorForSecondaryLabel
/// ///
public var bodyMaxLines = Int(5) public var bodyMaxLines = Int(5)
@ -232,7 +232,7 @@ public extension ProHUD.Configuration {
lazy var showNavButtons: (ProHUD.Alert, Alert) -> Void = { lazy var showNavButtons: (ProHUD.Alert, Alert) -> Void = {
return { (vc, config) in return { (vc, config) in
debugPrint(vc, "showNavButtons") debugPrint(vc, "showNavButtons")
let btn = UIButton.minimizeButton() let btn = ProHUD.Alert.Button.minimizeButton()
let bg = ProHUD.BlurView() let bg = ProHUD.BlurView()
bg.layer.masksToBounds = true bg.layer.masksToBounds = true
bg.layer.cornerRadius = config.cornerRadius bg.layer.cornerRadius = config.cornerRadius

View File

@ -116,31 +116,17 @@ public extension ProHUD {
/// - Parameter text: /// - Parameter text:
/// - Parameter action: /// - Parameter action:
@discardableResult public func addAction(style: UIAlertAction.Style, title: String?, action: (() -> Void)?) -> Alert { @discardableResult public func addAction(style: UIAlertAction.Style, title: String?, action: (() -> Void)?) -> Alert {
return addAction(custom: UIButton.actionButton(style: style, title: title), action: action) if let btn = privAddButton(custom: Button.actionButton(title: title), action: action) as? Button {
btn.update(style: style)
}
return self
} }
/// ///
/// - Parameter button: /// - Parameter button:
/// - Parameter action: /// - Parameter action:
@discardableResult public func addAction(custom button: UIButton , action: (() -> Void)?) -> Alert { @discardableResult public func addAction(custom button: UIButton, action: (() -> Void)?) -> Alert {
timeout = nil privAddButton(custom: button, action: action)
if actionStack.superview == nil {
contentStack.addArrangedSubview(actionStack)
}
self.view.layoutIfNeeded()
button.transform = .init(scaleX: 1, y: 0.001)
actionStack.addArrangedSubview(button)
UIView.animateForAlert {
button.transform = .identity
self.view.layoutIfNeeded()
}
addTouchUpAction(for: button) { [weak self] in
action?()
if button.tag == UIAlertAction.Style.cancel.rawValue {
self?.remove()
}
}
willLayoutSubviews()
return self return self
} }
@ -178,7 +164,9 @@ public extension ProHUD {
@discardableResult public func updateAction(index: Int, style: UIAlertAction.Style, title: String?, action: (() -> Void)?) -> Alert { @discardableResult public func updateAction(index: Int, style: UIAlertAction.Style, title: String?, action: (() -> Void)?) -> Alert {
return updateAction(index: index, button: { (btn) in return updateAction(index: index, button: { (btn) in
btn.setTitle(title, for: .normal) btn.setTitle(title, for: .normal)
btn.update(style: style) if let b = btn as? Button {
b.update(style: style)
}
btn.layoutIfNeeded() btn.layoutIfNeeded()
}, action: action) }, action: action)
} }
@ -254,6 +242,27 @@ fileprivate extension ProHUD.Alert {
DispatchQueue.main.asyncAfter(deadline: .now()+0.001, execute: willLayout!) DispatchQueue.main.asyncAfter(deadline: .now()+0.001, execute: willLayout!)
} }
@discardableResult private func privAddButton(custom button: UIButton, action: (() -> Void)?) -> UIButton {
timeout = nil
if actionStack.superview == nil {
contentStack.addArrangedSubview(actionStack)
}
self.view.layoutIfNeeded()
button.transform = .init(scaleX: 1, y: 0.001)
actionStack.addArrangedSubview(button)
UIView.animateForAlert {
button.transform = .identity
self.view.layoutIfNeeded()
}
addTouchUpAction(for: button) { [weak self] in
action?()
if button.tag == UIAlertAction.Style.cancel.rawValue {
self?.remove()
}
}
willLayoutSubviews()
return button
}
} }

View File

@ -8,59 +8,48 @@
import UIKit import UIKit
public extension ProHUD.Alert { internal extension ProHUD.Alert {
class Button: UIButton {
class func actionButton(title: String?) -> UIButton {
} let btn = Button(type: .system)
btn.setTitle(title, for: .normal)
extension UIButton { btn.layer.cornerRadius = alertConfig.cornerRadius / 2
btn.titleLabel?.font = alertConfig.buttonFont
class func actionButton(style: UIAlertAction.Style, title: String?) -> UIButton { return btn
let btn = UIButton(type: .system) }
btn.setTitle(title, for: .normal)
btn.layer.cornerRadius = alertConfig.cornerRadius / 2 func update(style: UIAlertAction.Style) {
btn.titleLabel?.font = alertConfig.buttonFont let pd = CGFloat(8)
btn.update(style: style) if style != .cancel {
return btn backgroundColor = dynamicColor.withAlphaComponent(0.04)
} contentEdgeInsets = .init(top: pd*1.5, left: pd*1.5, bottom: pd*1.5, right: pd*1.5)
} else {
func update(style: UIAlertAction.Style) { contentEdgeInsets = .init(top: pd*0.5, left: pd*1.5, bottom: pd*0.5, right: pd*1.5)
let pd = alertConfig.padding/2 }
if style != .cancel { switch style {
backgroundColor = .init(white: 0, alpha: 0.04) case .default:
contentEdgeInsets = .init(top: pd*1.5, left: pd*1.5, bottom: pd*1.5, right: pd*1.5) setTitleColor(tintColor, for: .normal)
} else { case .destructive:
contentEdgeInsets = .init(top: pd*0.5, left: pd*1.5, bottom: pd*0.5, right: pd*1.5) setTitleColor(.init(red: 244/255, green: 67/255, blue: 54/255, alpha: 1), for: .normal)
case .cancel:
setTitleColor(UIColorForSecondaryLabel, for: .normal)
@unknown default:
break
}
tag = style.rawValue
}
class func minimizeButton() -> UIButton {
let btn = Button(type: .system)
let pd = alertConfig.padding/2
btn.contentEdgeInsets = .init(top: pd*1.5, left: pd*1.5, bottom: pd*1.5, right: pd*1.5)
btn.imageEdgeInsets.right = pd*1.5
btn.setTitle(alertConfig.minimizeTitle, for: .normal)
btn.setTitleColor(UIColor(red:1.00, green:0.55, blue:0.21, alpha:1.00), for: .normal)
btn.titleLabel?.font = alertConfig.buttonFont
return btn
} }
switch style {
case .default:
setTitleColor(alertConfig.tintColor, for: .normal)
case .destructive:
setTitleColor(.init(red: 244/255, green: 67/255, blue: 54/255, alpha: 1), for: .normal)
case .cancel:
setTitleColor(.darkGray, for: .normal)
@unknown default:
break
}
tag = style.rawValue
}
class func minimizeButton() -> UIButton {
let btn = UIButton(type: .system)
// btn.contentEdgeInsets = .init(top: 8, left: 8, bottom: 8, right: 8)
let pd = alertConfig.padding/2
btn.contentEdgeInsets = .init(top: pd*1.5, left: pd*1.5, bottom: pd*1.5, right: pd*1.5)
// btn.imageEdgeInsets.left = pd*0.75
btn.imageEdgeInsets.right = pd*1.5
// btn.setImage(ProHUD.image(named: "ProHUDMinimize"), for: .normal)
// btn.layer.shadowOpacity = 0.15
// btn.layer.shadowOffset = .init(width: 0, height: 1.2)
// btn.layer.shadowRadius = 1.2
btn.setTitle(alertConfig.minimizeTitle, for: .normal)
btn.setTitleColor(UIColor(red:1.00, green:0.55, blue:0.21, alpha:1.00), for: .normal)
btn.titleLabel?.font = alertConfig.buttonFont
return btn
} }
} }

View File

@ -7,54 +7,149 @@
// //
import SnapKit import SnapKit
import Inspire
public extension ProHUD.Configuration { public extension ProHUD.Configuration {
struct Guard { struct Guard {
// MARK:
/// iPad /// iPad
public var maxWidth = CGFloat(556) public var cardMaxWidth = CGFloat(460)
/// /// 0
public var titleFont = UIFont.boldSystemFont(ofSize: 18) public var cardCornerRadius = CGFloat(16)
///
public var bodyFont = UIFont.systemFont(ofSize: 16)
/// 0
public var titleMaxLines = Int(0)
/// 0
public var bodyMaxLines = Int(0)
///
public var cornerRadius = CGFloat(16)
///
public var margin = CGFloat(8) public var margin = CGFloat(8)
///
public var padding = CGFloat(16) public var padding = CGFloat(16)
public var iconSize = CGSize(width: 48, height: 48) // MARK:
///
public var tintColor: UIColor?
// MARK:
///
public var titleFont = UIFont.boldSystemFont(ofSize: 22)
///
public var titleColor = UIColorForPrimaryLabel
///
public var bodyFont = UIFont.systemFont(ofSize: 18)
///
public var bodyColor = UIColorForSecondaryLabel
// MARK:
///
public var buttonFont = UIFont.boldSystemFont(ofSize: 18)
/// iPad
// public var buttonMaxWidth = CGFloat(460)
///
public var buttonCornerRadius = CGFloat(12)
lazy var loadTitleLabel: (ProHUD.Guard, Guard) -> Void = {
return { (vc, config) in
debugPrint(vc, "loadTitleLabel")
if vc.titleLabel == nil {
vc.titleLabel = UILabel()
vc.titleLabel?.font = config.titleFont
vc.titleLabel?.textColor = config.titleColor
vc.titleLabel?.numberOfLines = 0
vc.titleLabel?.textAlignment = .justified
}
}
}()
lazy var loadBodyLabel: (ProHUD.Guard, Guard) -> Void = {
return { (vc, config) in
debugPrint(vc, "loadBodyLabel")
if vc.bodyLabel == nil {
vc.bodyLabel = UILabel()
vc.bodyLabel?.font = config.bodyFont
vc.bodyLabel?.textColor = config.bodyColor
vc.bodyLabel?.numberOfLines = 0
vc.titleLabel?.textAlignment = .justified
}
}
}()
/// ///
lazy var loadSubviews: (ProHUD.Alert) -> Void = { lazy var loadSubviews: (ProHUD.Guard, Guard) -> Void = {
return { (vc) in return { (vc, config) in
debugPrint(vc, "loadSubviews") debugPrint(vc, "loadSubviews")
// background
vc.view.tintColor = config.tintColor
vc.view.backgroundColor = UIColor(white: 0, alpha: 0)
vc.view.addSubview(vc.contentView)
var width = UIScreen.main.bounds.width
if width > config.cardMaxWidth {
// iPad
width = config.cardMaxWidth
vc.contentView.layer.masksToBounds = true
vc.contentView.layer.cornerRadius = config.cardCornerRadius
} else {
vc.contentView.layer.shadowRadius = 4
vc.contentView.layer.shadowOffset = .init(width: 0, height: 2)
vc.contentView.layer.shadowOpacity = 0.12
}
vc.contentView.snp.makeConstraints { (mk) in
mk.centerX.equalToSuperview()
if UIDevice.current.userInterfaceIdiom == .phone {
if width == config.cardMaxWidth {
mk.bottom.equalToSuperview().offset(-Inspire.shared.screen.safeAreaInsets.bottom)
} else {
mk.bottom.equalToSuperview()
}
} else if UIDevice.current.userInterfaceIdiom == .pad {
mk.centerY.equalToSuperview()
}
mk.width.equalTo(width)
}
// stack
vc.contentView.contentView.addSubview(vc.contentStack)
vc.contentStack.snp.makeConstraints { (mk) in
mk.top.equalToSuperview().offset(config.padding + config.margin)
mk.centerX.equalToSuperview()
if width == config.cardMaxWidth {
mk.bottom.equalToSuperview().offset(-config.padding)
} else {
mk.bottom.equalToSuperview().offset(-config.margin-Inspire.shared.screen.safeAreaInsets.bottom)
}
if isPortrait {
mk.width.equalToSuperview().offset(-config.padding * 2)
} else {
mk.width.equalToSuperview().offset(-config.padding * 4)
}
}
vc.contentStack.addArrangedSubview(vc.textStack)
} }
}() }()
/// ///
lazy var updateFrame: (ProHUD.Alert) -> Void = { lazy var updateFrame: (ProHUD.Guard, Guard) -> Void = {
return { (vc) in return { (vc, config) in
debugPrint(vc, "updateFrame") debugPrint(vc, "updateFrame")
} }
}() }()
/// ///
/// - Parameter callback: /// - Parameter callback:
public mutating func loadSubviews(_ callback: @escaping (ProHUD.Alert) -> Void) { public mutating func loadSubviews(_ callback: @escaping (ProHUD.Guard, Guard) -> Void) {
loadSubviews = callback loadSubviews = callback
} }
/// ///
/// - Parameter callback: /// - Parameter callback:
public mutating func updateFrame(_ callback: @escaping (ProHUD.Alert) -> Void) { public mutating func updateFrame(_ callback: @escaping (ProHUD.Guard, Guard) -> Void) {
updateFrame = callback updateFrame = callback
} }
} }
} }
internal var guardConfig = ProHUD.Configuration.Guard()
public extension ProHUD {
static func configGuard(_ config: (inout Configuration.Guard) -> Void) {
config(&guardConfig)
}
}

View File

@ -6,4 +6,193 @@
// Copyright © 2019 Titan Studio. All rights reserved. // Copyright © 2019 Titan Studio. All rights reserved.
// //
import Foundation import SnapKit
public extension ProHUD {
class Guard: HUDController {
///
public var contentView = BlurView()
/// textStackactionStack)
public var contentStack: StackContainer = {
let stack = StackContainer()
stack.spacing = guardConfig.padding + guardConfig.margin
stack.alignment = .fill
return stack
}()
///
public var textStack: StackContainer = {
let stack = StackContainer()
stack.spacing = guardConfig.margin
stack.alignment = .fill
return stack
}()
public var titleLabel: UILabel?
public var bodyLabel: UILabel?
///
public var actionStack: StackContainer = {
let stack = StackContainer()
stack.alignment = .fill
stack.spacing = guardConfig.margin
return stack
}()
///
public var force = false
private let tag = Int(23905340)
private var displaying = false
// MARK:
///
/// - Parameter scene:
/// - Parameter title:
/// - Parameter message:
/// - Parameter icon:
public convenience init(title: String? = nil, message: String? = nil) {
self.init()
view = View()
view.tintColor = guardConfig.tintColor
if let _ = title {
loadTitle(title)
}
if let _ = message {
loadBody(message)
}
guardConfig.loadSubviews(self, guardConfig)
// willLayoutSubviews()
//
let tap = UITapGestureRecognizer(target: self, action: #selector(privDidTapped(_:)))
view.addGestureRecognizer(tap)
}
public override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
}
deinit {
debugPrint(self, "deinit")
}
public func push(to viewController: UIViewController? = nil) {
if let vc = viewController {
view.layoutIfNeeded()
vc.addChild(self)
vc.view.addSubview(view)
view.isUserInteractionEnabled = true
view.snp.makeConstraints { (mk) in
mk.edges.equalToSuperview()
}
if displaying == false {
translateOut()
}
displaying = true
UIView.animateForGuard {
self.translateIn()
}
}
}
public func pop() {
if displaying {
debugPrint("pop")
displaying = false
view.isUserInteractionEnabled = false
self.removeFromParent()
UIView.animateForGuard(animations: {
self.translateOut()
}) { (done) in
if self.displaying == false {
self.view.removeFromSuperview()
}
}
}
}
}
}
public extension ProHUD.Guard {
@discardableResult
func loadTitle(_ text: String?) -> UILabel {
guardConfig.loadTitleLabel(self, guardConfig)
let lb = titleLabel!
lb.text = text
if textStack.arrangedSubviews.count > 0 {
textStack.insertArrangedSubview(lb, at: 0)
} else {
textStack.addArrangedSubview(lb)
}
return lb
}
@discardableResult
func loadBody(_ text: String?) -> UILabel {
guardConfig.loadBodyLabel(self, guardConfig)
let lb = bodyLabel!
lb.text = text
textStack.addArrangedSubview(lb)
return lb
}
@discardableResult
func loadButton(style: UIAlertAction.Style, title: String?, action: (() -> Void)? = nil) -> UIButton {
let btn = Button.actionButton(title: title)
btn.titleLabel?.font = guardConfig.buttonFont
if actionStack.superview == nil {
contentStack.addArrangedSubview(actionStack)
}
actionStack.addArrangedSubview(btn)
btn.update(style: style)
addTouchUpAction(for: btn) { [weak self] in
action?()
if btn.tag == UIAlertAction.Style.cancel.rawValue {
self?.pop()
}
}
return btn
}
}
fileprivate extension ProHUD.Guard {
///
/// - Parameter sender:
@objc func privDidTapped(_ sender: UITapGestureRecognizer) {
let point = sender.location(in: contentView)
if point.x < 0 || point.y < 0 {
if force == false {
//
pop()
}
}
}
func translateIn() {
view.backgroundColor = UIColor(white: 0, alpha: 0.5)
contentView.transform = .identity
}
func translateOut() {
view.backgroundColor = UIColor(white: 0, alpha: 0)
contentView.transform = .init(translationX: 0, y: view.frame.size.height - contentView.frame.minY + guardConfig.margin)
}
}

View File

@ -6,4 +6,23 @@
// Copyright © 2019 Titan Studio. All rights reserved. // Copyright © 2019 Titan Studio. All rights reserved.
// //
import Foundation public extension ProHUD.Guard {
struct ViewModel {
///
public var title: String?
///
public var message: String?
public init(title: String? = nil, message: String? = nil, icon: UIImage? = nil) {
self.title = title
self.message = message
}
}
}

View File

@ -6,4 +6,69 @@
// Copyright © 2019 Titan Studio. All rights reserved. // Copyright © 2019 Titan Studio. All rights reserved.
// //
import Foundation import UIKit
internal extension ProHUD.Guard {
class View: UIView {
override func willMove(toSuperview newSuperview: UIView?) {
if let sv = newSuperview {
for v in sv.subviews {
if let vv = v as? ProHUD.Guard.View {
if vv.tag == self.tag {
UIView.animate(withDuration: 0.38, delay: 0.1, options: .curveEaseIn, animations: {
vv.alpha = 0
}) { (done) in
vv.removeFromSuperview()
}
}
}
}
}
}
// override func didMoveToSuperview() {
// if let _ = superview {
// snp.makeConstraints { (mk) in
//// mk.left.right.bottom.equalToSuperview()
// mk.edges.equalToSuperview()
// }
//// push(duration: duration)
// }
// }
}
class Button: UIButton {
class func actionButton(title: String?) -> Button {
let btn = Button(type: .system)
btn.setTitle(title, for: .normal)
btn.layer.cornerRadius = guardConfig.buttonCornerRadius
btn.titleLabel?.font = guardConfig.buttonFont
return btn
}
func update(style: UIAlertAction.Style) {
let pd = CGFloat(8)
if style != .cancel {
contentEdgeInsets = .init(top: pd*1.5+2, left: pd*1.5, bottom: pd*1.5+2, right: pd*1.5)
} else {
contentEdgeInsets = .init(top: pd*1+2, left: pd*1.5, bottom: pd*1+2, right: pd*1.5)
}
switch style {
case .default:
backgroundColor = tintColor
setTitleColor(.white, for: .normal)
case .destructive:
backgroundColor = .init(red: 244/255, green: 67/255, blue: 54/255, alpha: 1)
setTitleColor(.white, for: .normal)
case .cancel:
setTitleColor(UIColorForSecondaryLabel, for: .normal)
@unknown default:
break
}
tag = style.rawValue
}
}
}

View File

@ -55,8 +55,15 @@ public extension ProHUD {
init() { init() {
super.init(effect: UIBlurEffect(style: .light))
backgroundColor = UIColor.init(white: 1, alpha: 0.66) if #available(iOS 13.0, *) {
super.init(effect: UIBlurEffect(style: .systemMaterial))
// backgroundColor = UIColor.init(white: 1, alpha: 0.3)
} else {
super.init(effect: UIBlurEffect(style: .extraLight))
backgroundColor = UIColor.init(white: 1, alpha: 0.66)
}
} }
required init?(coder: NSCoder) { required init?(coder: NSCoder) {
@ -96,4 +103,11 @@ internal extension UIView {
animateEaseOut(duration: 1, delay: 0, animations: animations, completion: completion) animateEaseOut(duration: 1, delay: 0, animations: animations, completion: completion)
} }
class func animateForGuard(animations: @escaping () -> Void) {
animateForGuard(animations: animations, completion: nil)
}
class func animateForGuard(animations: @escaping () -> Void, completion: ((Bool) -> Void)? = nil) {
animateEaseOut(duration: 0.6, delay: 0, animations: animations, completion: completion)
}
} }

View File

@ -48,3 +48,56 @@ internal var isPortrait: Bool {
return false return false
} }
} }
internal var dynamicColor: UIColor {
if #available(iOS 13.0, *) {
let color = UIColor { (traitCollection: UITraitCollection) -> UIColor in
if traitCollection.userInterfaceStyle == .dark {
return .white
} else {
return .black
}
}
return color
} else {
// Fallback on earlier versions
}
return .init(white: 0.2, alpha: 1)
}
internal var UIColorForPrimaryLabel: UIColor {
return dynamicColor.withAlphaComponent(0.75)
}
internal var UIColorForSecondaryLabel: UIColor {
return dynamicColor.withAlphaComponent(0.6)
}
internal extension UIColor {
var dynamicColor: UIColor {
if #available(iOS 13.0, *) {
let color = UIColor { (traitCollection: UITraitCollection) -> UIColor in
if traitCollection.userInterfaceStyle == .dark {
return .white
} else {
return .black
}
}
return color
} else {
// Fallback on earlier versions
}
return .init(white: 0.2, alpha: 1)
}
var dynamicPrimaryLabelColor: UIColor {
return dynamicColor.withAlphaComponent(0.75)
}
var dynamicSecondaryLabelColor: UIColor {
return dynamicColor.withAlphaComponent(0.6)
}
}

View File

@ -29,10 +29,12 @@ public extension ProHUD.Configuration {
public var iconSize = CGSize(width: 48, height: 48) public var iconSize = CGSize(width: 48, height: 48)
public var tintColor: UIColor?
/// ///
lazy var loadSubviews: (ProHUD.Toast) -> Void = { lazy var loadSubviews: (ProHUD.Toast) -> Void = {
return { (vc) in return { (vc) in
debugPrint(vc, "loadSubviews") debugPrint(vc, "loadSubviews")
vc.view.tintColor = toastConfig.tintColor
vc.view.addSubview(vc.titleLabel) vc.view.addSubview(vc.titleLabel)
vc.view.addSubview(vc.bodyLabel) vc.view.addSubview(vc.bodyLabel)
vc.view.addSubview(vc.imageView) vc.view.addSubview(vc.imageView)
@ -64,11 +66,10 @@ public extension ProHUD.Configuration {
} }
let img = vc.vm.icon ?? ProHUD.image(named: imgStr) let img = vc.vm.icon ?? ProHUD.image(named: imgStr)
vc.imageView.image = img vc.imageView.image = img
vc.titleLabel.textColor = UIColorForPrimaryLabel
vc.titleLabel.text = vc.vm.title vc.titleLabel.text = vc.vm.title
vc.bodyLabel.textColor = UIColorForSecondaryLabel
vc.bodyLabel.text = vc.vm.message vc.bodyLabel.text = vc.vm.message
vc.tintColor = vc.vm.scene.tintColor
} }
}() }()
@ -77,7 +78,6 @@ public extension ProHUD.Configuration {
return { (vc) in return { (vc) in
debugPrint(vc, "layoutSubviews") debugPrint(vc, "layoutSubviews")
let config = toastConfig let config = toastConfig
let scene = vc.vm.scene let scene = vc.vm.scene
vc.imageView.snp.makeConstraints { (mk) in vc.imageView.snp.makeConstraints { (mk) in
@ -97,16 +97,7 @@ public extension ProHUD.Configuration {
mk.leading.trailing.equalTo(vc.titleLabel) mk.leading.trailing.equalTo(vc.titleLabel)
mk.bottom.lessThanOrEqualToSuperview().offset(-config.padding) mk.bottom.lessThanOrEqualToSuperview().offset(-config.padding)
} }
if [.default, .loading].contains(vc.vm.scene) {
vc.blurMask(.extraLight)
} else {
vc.blurMask(nil)
}
if let bv = vc.blurView {
vc.backgroundView = bv
} else {
vc.backgroundView.backgroundColor = vc.vm.scene.backgroundColor
}
vc.view.layoutIfNeeded() vc.view.layoutIfNeeded()
} }
}() }()

View File

@ -24,7 +24,7 @@ public extension ProHUD {
/// ///
internal lazy var titleLabel: UILabel = { internal lazy var titleLabel: UILabel = {
let lb = UILabel() let lb = UILabel()
lb.textColor = UIColor.init(white: 0.2, alpha: 1) lb.textColor = UIColorForPrimaryLabel
lb.font = toastConfig.titleFont lb.font = toastConfig.titleFont
lb.textAlignment = .justified lb.textAlignment = .justified
lb.numberOfLines = toastConfig.titleMaxLines lb.numberOfLines = toastConfig.titleMaxLines
@ -34,27 +34,25 @@ public extension ProHUD {
/// ///
internal lazy var bodyLabel: UILabel = { internal lazy var bodyLabel: UILabel = {
let lb = UILabel() let lb = UILabel()
lb.textColor = .darkGray lb.textColor = UIColorForSecondaryLabel
lb.font = toastConfig.bodyFont lb.font = toastConfig.bodyFont
lb.textAlignment = .justified lb.textAlignment = .justified
lb.numberOfLines = toastConfig.bodyMaxLines lb.numberOfLines = toastConfig.bodyMaxLines
return lb return lb
}() }()
/// ///
var blurView: UIVisualEffectView? var backgroundView: UIVisualEffectView = {
let vev = UIVisualEffectView()
/// iOS13window if #available(iOS 13.0, *) {
var backgroundView = UIView() vev.effect = UIBlurEffect.init(style: .systemMaterial)
} else {
/// vev.effect = UIBlurEffect.init(style: .extraLight)
open var tintColor: UIColor!{
didSet {
imageView.tintColor = tintColor
titleLabel.textColor = tintColor
bodyLabel.textColor = tintColor
} }
} vev.layer.masksToBounds = true
vev.layer.cornerRadius = toastConfig.cornerRadius
return vev
}()
/// ///
public var vm = ViewModel() public var vm = ViewModel()
@ -118,23 +116,6 @@ public extension ProHUD {
} }
} }
@discardableResult
func blurMask(_ blurEffectStyle: UIBlurEffect.Style?) -> Toast {
if let s = blurEffectStyle {
if let bv = blurView {
bv.effect = UIBlurEffect.init(style: s)
} else {
blurView = UIVisualEffectView(effect: UIBlurEffect.init(style: s))
blurView?.layer.masksToBounds = true
blurView?.layer.cornerRadius = toastConfig.cornerRadius
}
} else {
blurView?.removeFromSuperview()
blurView = nil
}
return self
}
@discardableResult @discardableResult
func update(title: String?) -> Toast { func update(title: String?) -> Toast {
vm.title = title vm.title = title

View File

@ -29,27 +29,27 @@ public extension ProHUD.Toast {
/// ///
case error case error
public var backgroundColor: UIColor { // public var backgroundColor: UIColor {
switch self { // switch self {
case .success: // case .success:
return UIColor.green // return UIColor.green
case .warning: // case .warning:
return UIColor.yellow // return UIColor.yellow
case .error: // case .error:
return UIColor.red // return UIColor.red
default: // default:
return .clear // return .clear
} // }
} // }
//
public var tintColor: UIColor { // public var tintColor: UIColor {
switch self { // switch self {
case .success, .error: // case .success, .error:
return .white // return .white
default: // default:
return UIColor.darkGray // return UIColor.darkGray
} // }
} // }
} }
struct ViewModel { struct ViewModel {