From 7e672707cfc4ccc2c916c159a0de272b54bcbec4 Mon Sep 17 00:00:00 2001 From: xaoxuu Date: Thu, 27 Apr 2023 18:14:09 +0800 Subject: [PATCH] =?UTF-8?q?UI=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- PHDemo/PHDemo/AlertVC.swift | 36 ++++- Sources/ProHUD/Alert/Alert.swift | 7 +- Sources/ProHUD/Alert/AlertButton.swift | 16 ++ .../ProHUD/Alert/AlertConvenienceLayout.swift | 35 +++-- Sources/ProHUD/Alert/AlertDefaultLayout.swift | 40 +++-- .../ProHUD/Core/Controllers/Controller.swift | 5 + .../ProHUD/Core/Protocols/CommonLayout.swift | 5 +- .../Core/Protocols/ConvenienceLayout.swift | 9 +- .../ProHUD/Core/Protocols/DefaultLayout.swift | 4 +- .../ProHUD/Core/Utils/RotateAnimation.swift | 2 +- Sources/ProHUD/Core/Views/Button.swift | 7 +- Sources/ProHUD/Sheet/Sheet.swift | 4 +- Sources/ProHUD/Sheet/SheetButton.swift | 4 +- .../ProHUD/Sheet/SheetConvenienceLayout.swift | 14 +- Sources/ProHUD/Sheet/SheetDefaultLayout.swift | 9 +- Sources/ProHUD/Toast/Toast.swift | 4 +- Sources/ProHUD/Toast/ToastButton.swift | 4 +- .../ProHUD/Toast/ToastConvenienceLayout.swift | 145 ++++++++++++++---- Sources/ProHUD/Toast/ToastDefaultLayout.swift | 5 +- 19 files changed, 264 insertions(+), 91 deletions(-) create mode 100644 Sources/ProHUD/Alert/AlertButton.swift diff --git a/PHDemo/PHDemo/AlertVC.swift b/PHDemo/PHDemo/AlertVC.swift index a4d80df..f090a6b 100644 --- a/PHDemo/PHDemo/AlertVC.swift +++ b/PHDemo/PHDemo/AlertVC.swift @@ -69,20 +69,46 @@ class AlertVC: ListVC { } } list.add(title: "文字 + 按钮") { section in + section.add(title: "只有一小段文字 + 无背景色按钮") { + Alert { alert in + alert.config.boldTextFont = .systemFont(ofSize: 15) + alert.config.buttonFont = .systemFont(ofSize: 15) + alert.config.cardCornerRadius = 12 + alert.vm.title = "你正在使用移动网络观看" + } .onViewDidLoad { vc in + guard let alert = vc as? Alert else { + return + } + alert.add(contentSpacing: 30) + let v = UIView() + v.backgroundColor = UIColor("#f2f2f2") + alert.add(subview: v).snp.makeConstraints { make in + make.left.right.equalToSuperview() + make.height.equalTo(1) + } + alert.add(contentSpacing: 16) + alert.add(action: "确定", style: .plain(textColor: UIColor("#14cccc"))) + + } + } section.add(title: "只有一段文字 + 无背景色按钮") { Alert { alert in alert.config.boldTextFont = .systemFont(ofSize: 15) alert.config.buttonFont = .systemFont(ofSize: 15) alert.config.cardCornerRadius = 12 - alert.vm.title = "为了维护社区氛围,上麦用户需进行主播认证" + } .onViewDidLoad { vc in + guard let alert = vc as? Alert else { + return + } + alert.add(contentSpacing: 30) let v = UIView() - v.backgroundColor = UIColor("#F7F7F7") + v.backgroundColor = UIColor("#f2f2f2") alert.add(subview: v).snp.makeConstraints { make in make.left.right.equalToSuperview() make.height.equalTo(1) } - alert.add(spacing: 16) + alert.add(contentSpacing: 16) alert.add(action: "取消", style: .plain(textColor: UIColor("#939999"))) alert.add(action: "确定", style: .plain(textColor: UIColor("#14cccc"))) } @@ -281,7 +307,7 @@ class AlertVC: ListVC { slider.maximumValue = 100 slider.value = 50 alert.add(action: slider) - alert.add(spacing: 24, for: alert.actionStack) + alert.add(actionSpacing: 124) alert.add(action: "取消", style: .gray) } } @@ -305,7 +331,7 @@ class AlertVC: ListVC { // Fallback on earlier versions } alert.config.actionAxis = .vertical - alert.add(spacing: 24, for: alert.actionStack) + alert.add(contentSpacing: 24) alert.add(action: "OK", style: .gray) } } diff --git a/Sources/ProHUD/Alert/Alert.swift b/Sources/ProHUD/Alert/Alert.swift index 3c155bf..a6edc92 100644 --- a/Sources/ProHUD/Alert/Alert.swift +++ b/Sources/ProHUD/Alert/Alert.swift @@ -46,7 +46,7 @@ public class Alert: ProHUD.Controller { let lb = UILabel() lb.textColor = config.primaryLabelColor lb.font = config.titleFontByDefault - lb.textAlignment = .justified + lb.textAlignment = .left lb.numberOfLines = config.titleMaxLines return lb }() @@ -56,7 +56,7 @@ public class Alert: ProHUD.Controller { let lb = UILabel() lb.textColor = config.primaryLabelColor lb.font = config.bodyFontByDefault - lb.textAlignment = .justified + lb.textAlignment = .left lb.numberOfLines = config.bodyMaxLines return lb }() @@ -100,7 +100,8 @@ public class Alert: ProHUD.Controller { public override func viewDidLoad() { super.viewDidLoad() view.tintColor = config.tintColor - reloadData() + reloadData(animated: false) + navEvents[.onViewDidLoad]?(self) } required init?(coder: NSCoder) { diff --git a/Sources/ProHUD/Alert/AlertButton.swift b/Sources/ProHUD/Alert/AlertButton.swift new file mode 100644 index 0000000..418c1af --- /dev/null +++ b/Sources/ProHUD/Alert/AlertButton.swift @@ -0,0 +1,16 @@ +// +// AlertButton.swift +// +// +// Created by xaoxuu on 2023/4/27. +// + +import UIKit + +public class AlertButton: Button { + override var customEdgeInset: UIEdgeInsets { + .init(top: 12, left: 24, bottom: 12, right: 24) + } +} + + diff --git a/Sources/ProHUD/Alert/AlertConvenienceLayout.swift b/Sources/ProHUD/Alert/AlertConvenienceLayout.swift index 6ff2804..024ef91 100644 --- a/Sources/ProHUD/Alert/AlertConvenienceLayout.swift +++ b/Sources/ProHUD/Alert/AlertConvenienceLayout.swift @@ -14,7 +14,7 @@ extension Alert: InternalConvenienceLayout { insert(action: action, at: actionStack.arrangedSubviews.count) } @discardableResult public func insert(action: Action, at index: Int) -> Button { - let btn = Button(config: config, action: action) + let btn = AlertButton(config: config, action: action) if index < actionStack.arrangedSubviews.count { actionStack.insertArrangedSubview(btn, at: index) } else { @@ -32,7 +32,7 @@ extension Alert: InternalConvenienceLayout { self?.pop() } } - if isViewLoaded { + if isViewDisplayed { self.actionStack.layoutIfNeeded() UIView.animateEaseOut(duration: config.animateDurationForReloadByDefault) { self.view.layoutIfNeeded() @@ -78,7 +78,7 @@ extension Alert: InternalConvenienceLayout { buttonEvents[view] = nil } } - if isViewLoaded { + if isViewDisplayed { UIView.animateEaseOut(duration: config.animateDurationForReloadByDefault) { self.actionStack.layoutIfNeeded() self.view.layoutIfNeeded() @@ -105,18 +105,33 @@ extension Alert: InternalConvenienceLayout { // MARK: 布局工具 - public func add(spacing: CGFloat) { - add(spacing: spacing, for: contentStack) - } - - public func add(spacing: CGFloat, for stack: UIStackView) { + public func set(spacing: CGFloat, after: UIView?, in stack: UIStackView) { if #available(iOS 11.0, *) { - if let last = stack.arrangedSubviews.last { - stack.setCustomSpacing(spacing, after: last) + if let after = after ?? stack.arrangedSubviews.last { + stack.setCustomSpacing(spacing, after: after) } } } + public func set(contentSpacing: CGFloat, after: UIView?) { + set(spacing: contentSpacing, after: after, in: contentStack) + } + public func set(textSpacing: CGFloat, after: UIView?) { + set(spacing: textSpacing, after: after, in: textStack) + } + public func set(actionSpacing: CGFloat, after: UIView?) { + set(spacing: actionSpacing, after: after, in: actionStack) + } + public func add(contentSpacing: CGFloat) { + set(spacing: contentSpacing, after: nil, in: contentStack) + } + public func add(textSpacing: CGFloat) { + set(spacing: textSpacing, after: nil, in: textStack) + } + public func add(actionSpacing: CGFloat) { + set(spacing: actionSpacing, after: nil, in: actionStack) + } + // MARK: 完全自定义布局 @discardableResult public func set(customView: UIView) -> UIView { diff --git a/Sources/ProHUD/Alert/AlertDefaultLayout.swift b/Sources/ProHUD/Alert/AlertDefaultLayout.swift index 983d23c..af03c9d 100644 --- a/Sources/ProHUD/Alert/AlertDefaultLayout.swift +++ b/Sources/ProHUD/Alert/AlertDefaultLayout.swift @@ -13,10 +13,13 @@ extension Alert: DefaultLayout { return config } - func reloadDataByDefault() { + func reloadData(animated: Bool) { + if self.cfg.customReloadData?(self) == true { + return + } let isFirstLayout: Bool if contentView.superview == nil { - isFirstLayout = true + isFirstLayout = animated // 布局主容器视图 loadContentViewIfNeeded() } else { @@ -42,19 +45,22 @@ extension Alert: DefaultLayout { contentView.layoutIfNeeded() // 动画 - if isFirstLayout { - view.layoutIfNeeded() - imageView.transform = .init(scaleX: 0.7, y: 0.7) - UIView.animateEaseOut(duration: config.animateDurationForReloadByDefault) { - self.view.layoutIfNeeded() - self.imageView.transform = .identity + if animated { + if isFirstLayout { + view.layoutIfNeeded() + imageView.transform = .init(scaleX: 0.7, y: 0.7) + UIView.animateEaseOut(duration: config.animateDurationForReloadByDefault) { + self.view.layoutIfNeeded() + self.imageView.transform = .identity + } + } else { + UIView.animateEaseOut(duration: config.animateDurationForReloadByDefault) { + self.view.layoutIfNeeded() + } } } else { - UIView.animateEaseOut(duration: config.animateDurationForReloadByDefault) { - self.view.layoutIfNeeded() - } + view.layoutIfNeeded() } - } func loadContentViewIfNeeded() { @@ -166,14 +172,14 @@ extension Alert { contentStack.insertArrangedSubview(textStack, at: 0) } textStack.snp.remakeConstraints { (mk) in - mk.top.greaterThanOrEqualTo(contentView).inset(config.padding*1.75) - mk.bottom.lessThanOrEqualTo(contentView).inset(config.padding*1.75) + mk.top.greaterThanOrEqualTo(contentView).inset(config.padding*1.875) + mk.bottom.lessThanOrEqualTo(contentView).inset(config.padding*1.875) if UIScreen.main.bounds.width < 414 { - mk.left.greaterThanOrEqualTo(contentView).inset(config.padding*1.5) - mk.right.lessThanOrEqualTo(contentView).inset(config.padding*1.5) - } else { mk.left.greaterThanOrEqualTo(contentView).inset(config.padding*2) mk.right.lessThanOrEqualTo(contentView).inset(config.padding*2) + } else { + mk.left.greaterThanOrEqualTo(contentView).inset(config.padding*3) + mk.right.lessThanOrEqualTo(contentView).inset(config.padding*3) } } } diff --git a/Sources/ProHUD/Core/Controllers/Controller.swift b/Sources/ProHUD/Core/Controllers/Controller.swift index 3a8c4a2..e9dcf81 100644 --- a/Sources/ProHUD/Core/Controllers/Controller.swift +++ b/Sources/ProHUD/Core/Controllers/Controller.swift @@ -58,6 +58,11 @@ open class Controller: UIViewController { var navEvents = [NavEvent: ((Controller) -> Void)]() + @discardableResult public func onViewDidLoad(_ callback: ((_ vc: Controller) -> Void)?) -> Controller { + navEvents[.onViewDidLoad] = callback + return self + } + @discardableResult public func onViewWillAppear(_ callback: ((_ vc: Controller) -> Void)?) -> Controller { navEvents[.onViewWillAppear] = callback return self diff --git a/Sources/ProHUD/Core/Protocols/CommonLayout.swift b/Sources/ProHUD/Core/Protocols/CommonLayout.swift index b14808a..af60831 100644 --- a/Sources/ProHUD/Core/Protocols/CommonLayout.swift +++ b/Sources/ProHUD/Core/Protocols/CommonLayout.swift @@ -17,10 +17,7 @@ public extension CommonLayout { guard let self = self as? DefaultLayout else { return } - if self.cfg.customReloadData?(self) == true { - return - } - self.reloadDataByDefault() + self.reloadData(animated: true) } } diff --git a/Sources/ProHUD/Core/Protocols/ConvenienceLayout.swift b/Sources/ProHUD/Core/Protocols/ConvenienceLayout.swift index 8145205..f38639c 100644 --- a/Sources/ProHUD/Core/Protocols/ConvenienceLayout.swift +++ b/Sources/ProHUD/Core/Protocols/ConvenienceLayout.swift @@ -54,9 +54,12 @@ public protocol ConvenienceLayout { // MARK: 布局工具 - /// 增加空隙(仅iOS11以上可用) - /// - Parameter spacing: 自定义空隙 - func add(spacing: CGFloat) + /// 设置stack容器内的元素间距 + /// - Parameters: + /// - spacing: 间距 + /// - after: 哪个view后面 + /// - stack: 在哪个stack容器内 + func set(spacing: CGFloat, after: UIView?, in stack: UIStackView) // MARK: 自定义布局 diff --git a/Sources/ProHUD/Core/Protocols/DefaultLayout.swift b/Sources/ProHUD/Core/Protocols/DefaultLayout.swift index 723a721..f6021a1 100644 --- a/Sources/ProHUD/Core/Protocols/DefaultLayout.swift +++ b/Sources/ProHUD/Core/Protocols/DefaultLayout.swift @@ -11,9 +11,7 @@ protocol DefaultLayout: CommonLayout { var cfg: Configuration { get } - func reloadDataByDefault() - - func loadContentViewIfNeeded() + func reloadData(animated: Bool) } diff --git a/Sources/ProHUD/Core/Utils/RotateAnimation.swift b/Sources/ProHUD/Core/Utils/RotateAnimation.swift index 50c0b56..dac7fbb 100644 --- a/Sources/ProHUD/Core/Utils/RotateAnimation.swift +++ b/Sources/ProHUD/Core/Utils/RotateAnimation.swift @@ -12,7 +12,7 @@ extension LoadingAnimation { /// 更新进度(如果需要显示进度,需要先调用一次 updateProgress(0) 来初始化) /// - Parameter progress: 进度(0~1) public func update(progress: CGFloat) { - guard isViewLoaded else { return } + guard isViewDisplayed else { return } guard let superview = imageView.superview else { return } if progressView == nil { let width = imageView.frame.size.width + ProgressView.lineWidth * 2 diff --git a/Sources/ProHUD/Core/Views/Button.swift b/Sources/ProHUD/Core/Views/Button.swift index e498b36..15b0d36 100644 --- a/Sources/ProHUD/Core/Views/Button.swift +++ b/Sources/ProHUD/Core/Views/Button.swift @@ -13,12 +13,13 @@ open class Button: UIButton { public internal(set) var action: Action? - var edgeInset: CGFloat { 8 * 1.5 } + var customEdgeInset: UIEdgeInsets { + .init(top: 12, left: 24, bottom: 12, right: 24) + } public override init(frame: CGRect) { super.init(frame: frame) - let padding = edgeInset - contentEdgeInsets = .init(top: padding, left: padding * 2, bottom: padding, right: padding * 2) + contentEdgeInsets = customEdgeInset addTarget(self, action: #selector(self._onTouchUp(_:)), for: [.touchUpInside, .touchUpOutside]) addTarget(self, action: #selector(self._onTouchDown(_:)), for: .touchDown) addTarget(self, action: #selector(self._onTouchUpInside(_:)), for: .touchUpInside) diff --git a/Sources/ProHUD/Sheet/Sheet.swift b/Sources/ProHUD/Sheet/Sheet.swift index 31896a6..e34a9e0 100644 --- a/Sources/ProHUD/Sheet/Sheet.swift +++ b/Sources/ProHUD/Sheet/Sheet.swift @@ -64,10 +64,12 @@ public class Sheet: Controller { let tap = UITapGestureRecognizer(target: self, action: #selector(_onTappedBackground(_:))) backgroundView.addGestureRecognizer(tap) - reloadData() + reloadData(animated: false) _translateOut() + navEvents[.onViewDidLoad]?(self) + } } diff --git a/Sources/ProHUD/Sheet/SheetButton.swift b/Sources/ProHUD/Sheet/SheetButton.swift index 87ec9cc..0aaa69c 100644 --- a/Sources/ProHUD/Sheet/SheetButton.swift +++ b/Sources/ProHUD/Sheet/SheetButton.swift @@ -8,5 +8,7 @@ import UIKit public class SheetButton: Button { - override var edgeInset: CGFloat { 8 * 1.75 } + override var customEdgeInset: UIEdgeInsets { + .init(top: 14, left: 28, bottom: 14, right: 28) + } } diff --git a/Sources/ProHUD/Sheet/SheetConvenienceLayout.swift b/Sources/ProHUD/Sheet/SheetConvenienceLayout.swift index d7198e7..65e5d75 100644 --- a/Sources/ProHUD/Sheet/SheetConvenienceLayout.swift +++ b/Sources/ProHUD/Sheet/SheetConvenienceLayout.swift @@ -28,7 +28,7 @@ extension Sheet: ConvenienceLayout { self?.pop() } } - if isViewLoaded { + if isViewDisplayed { self.contentStack.layoutIfNeeded() UIView.animateEaseOut(duration: config.animateDurationForReloadByDefault) { self.view.layoutIfNeeded() @@ -74,7 +74,7 @@ extension Sheet: ConvenienceLayout { buttonEvents[view] = nil } } - if isViewLoaded { + if isViewDisplayed { UIView.animateEaseOut(duration: config.animateDurationForReloadByDefault) { self.contentStack.layoutIfNeeded() self.view.layoutIfNeeded() @@ -92,14 +92,18 @@ extension Sheet: ConvenienceLayout { // MARK: 布局工具 - public func add(spacing: CGFloat) { + public func set(spacing: CGFloat, after: UIView?, in stack: UIStackView) { if #available(iOS 11.0, *) { - if let last = contentStack.arrangedSubviews.last { - contentStack.setCustomSpacing(spacing, after: last) + if let after = after ?? stack.arrangedSubviews.last { + stack.setCustomSpacing(spacing, after: after) } } } + public func add(spacing: CGFloat) { + set(spacing: spacing, after: nil, in: contentStack) + } + // MARK: 完全自定义布局 @discardableResult public func set(customView: UIView) -> UIView { diff --git a/Sources/ProHUD/Sheet/SheetDefaultLayout.swift b/Sources/ProHUD/Sheet/SheetDefaultLayout.swift index 89e01d2..9c2ce45 100644 --- a/Sources/ProHUD/Sheet/SheetDefaultLayout.swift +++ b/Sources/ProHUD/Sheet/SheetDefaultLayout.swift @@ -13,7 +13,10 @@ extension Sheet: DefaultLayout { return config } - func reloadDataByDefault() { + func reloadData(animated: Bool) { + if self.cfg.customReloadData?(self) == true { + return + } // background if backgroundView.superview == nil { view.insertSubview(backgroundView, at: 0) @@ -30,10 +33,9 @@ extension Sheet: DefaultLayout { self.view.layoutIfNeeded() } } - } - func loadContentViewIfNeeded() { + private func loadContentViewIfNeeded() { contentView.layer.cornerRadiusWithContinuous = config.cardCornerRadiusByDefault if contentView.superview != view { view.insertSubview(contentView, aboveSubview: backgroundView) @@ -92,5 +94,4 @@ extension Sheet: DefaultLayout { } - } diff --git a/Sources/ProHUD/Toast/Toast.swift b/Sources/ProHUD/Toast/Toast.swift index 6013176..a42412a 100644 --- a/Sources/ProHUD/Toast/Toast.swift +++ b/Sources/ProHUD/Toast/Toast.swift @@ -124,7 +124,9 @@ public class Toast: Controller { let pan = UIPanGestureRecognizer(target: self, action: #selector(_onPanGesture(_:))) view.addGestureRecognizer(pan) - reloadData() + reloadData(animated: false) + navEvents[.onViewDidLoad]?(self) + } public func onTapped(action: @escaping (_ toast: Toast) -> Void) { diff --git a/Sources/ProHUD/Toast/ToastButton.swift b/Sources/ProHUD/Toast/ToastButton.swift index 732ba64..11a9a25 100644 --- a/Sources/ProHUD/Toast/ToastButton.swift +++ b/Sources/ProHUD/Toast/ToastButton.swift @@ -8,6 +8,8 @@ import UIKit public class ToastButton: Button { - override var edgeInset: CGFloat { 8 * 1.25 } + override var customEdgeInset: UIEdgeInsets { + .init(top: 10, left: 24, bottom: 10, right: 24) + } } diff --git a/Sources/ProHUD/Toast/ToastConvenienceLayout.swift b/Sources/ProHUD/Toast/ToastConvenienceLayout.swift index 26c6e0f..c6b98df 100644 --- a/Sources/ProHUD/Toast/ToastConvenienceLayout.swift +++ b/Sources/ProHUD/Toast/ToastConvenienceLayout.swift @@ -7,21 +7,35 @@ import UIKit -public extension Toast { +extension Toast: ConvenienceLayout { - @discardableResult func add(subview: UIView) -> UIView { - if contentStack.superview != nil { - contentStack.removeFromSuperview() + // MARK: 增加 + + /// 增加一个按钮 + /// - Parameters: + /// - title: 标题 + /// - style: 样式 + /// - identifier: 唯一标识符 + /// - handler: 点击事件 + /// - Returns: 按钮实例 + @discardableResult public func add(action title: String, style: Action.Style = .tinted, identifier: String? = nil, handler: ((_ toast: Toast) -> Void)? = nil) -> Button { + if let handler = handler { + let action = Action(identifier: identifier, style: style, title: title) { vc in + if let vc = vc as? Toast { + handler(vc) + } + } + return add(action: action) + } else { + return add(action: .init(identifier: identifier, style: style, title: title, handler: nil)) } - contentView.addSubview(subview) - return subview } - @discardableResult func add(action: Action) -> Button { + @discardableResult public func add(action: Action) -> Button { insert(action: action, at: actionStack.arrangedSubviews.count) } - @discardableResult func insert(action: Action, at index: Int) -> Button { + @discardableResult public func insert(action: Action, at index: Int) -> Button { let btn = ToastButton(config: config, action: action) if index < actionStack.arrangedSubviews.count { actionStack.insertArrangedSubview(btn, at: index) @@ -37,7 +51,7 @@ public extension Toast { self?.pop() } } - if isViewLoaded { + if isViewDisplayed { self.actionStack.layoutIfNeeded() UIView.animateEaseOut(duration: config.animateDurationForReloadByDefault) { self.view.layoutIfNeeded() @@ -46,36 +60,111 @@ public extension Toast { return btn } - // MARK: 布局工具 - func add(spacing: CGFloat) { - if #available(iOS 11.0, *) { - if let last = contentStack.arrangedSubviews.last { - contentStack.setCustomSpacing(spacing, after: last) + // MARK: 查找 + public func button(for identifier: String) -> Button? { + if let index = actionIndex(for: identifier) { + return contentStack.arrangedSubviews[index] as? Button + } + return nil + } + + // MARK: 更新 + public func update(action title: String, style: Action.Style? = nil, for identifier: String) { + if let btn = button(for: identifier), let act = btn.action { + act.title = title + if let style = style { + act.style = style } + btn.update(config: config, action: act) } } - /// 增加一个按钮 - /// - Parameters: - /// - title: 标题 - /// - style: 样式 - /// - identifier: 唯一标识符 - /// - handler: 点击事件 - /// - Returns: 按钮实例 - @discardableResult func add(action title: String, style: Action.Style = .tinted, identifier: String? = nil, handler: ((_ toast: Toast) -> Void)? = nil) -> Button { - if let handler = handler { - let action = Action(identifier: identifier, style: style, title: title) { vc in - if let vc = vc as? Toast { - handler(vc) + // MARK: 删除 + + public func remove(actions finder: Action.Filter) { + if finder.ids.count > 0 { + for identifier in finder.ids { + while let index = actionIndex(for: identifier), index < contentStack.arrangedSubviews.count { + let view = contentStack.arrangedSubviews[index] + contentStack.removeArrangedSubview(view) + view.removeFromSuperview() + buttonEvents[view] = nil } } - return add(action: action) } else { - return add(action: .init(identifier: identifier, style: style, title: title, handler: nil)) + for view in contentStack.arrangedSubviews { + contentStack.removeArrangedSubview(view) + view.removeFromSuperview() + buttonEvents[view] = nil + } + } + if isViewDisplayed { + UIView.animateEaseOut(duration: config.animateDurationForReloadByDefault) { + self.contentStack.layoutIfNeeded() + self.view.layoutIfNeeded() + } } } + // MARK: 自定义控件 + + @discardableResult public func add(subview: UIView) -> UIView { + if contentStack.superview != nil { + contentStack.removeFromSuperview() + } + contentView.addSubview(subview) + return subview + } + + // MARK: 布局工具 + + public func set(spacing: CGFloat, after: UIView?, in stack: UIStackView) { + if #available(iOS 11.0, *) { + if let after = after ?? stack.arrangedSubviews.last { + stack.setCustomSpacing(spacing, after: after) + } + } + } + + public func set(contentSpacing: CGFloat, after: UIView?) { + set(spacing: contentSpacing, after: after, in: contentStack) + } + public func set(textSpacing: CGFloat, after: UIView?) { + set(spacing: textSpacing, after: after, in: textStack) + } + public func set(actionSpacing: CGFloat, after: UIView?) { + set(spacing: actionSpacing, after: after, in: actionStack) + } + public func add(contentSpacing: CGFloat) { + set(spacing: contentSpacing, after: nil, in: contentStack) + } + public func add(textSpacing: CGFloat) { + set(spacing: textSpacing, after: nil, in: textStack) + } + public func add(actionSpacing: CGFloat) { + set(spacing: actionSpacing, after: nil, in: actionStack) + } + + + // MARK: 完全自定义布局 + + public func set(customView: UIView) -> UIView { + self.customView = customView + contentView.addSubview(customView) + return customView + } + + // MARK: internal + func actionIndex(for identifier: String) -> Int? { + let arr = contentStack.arrangedSubviews.compactMap({ $0 as? Button }) + for i in 0 ..< arr.count { + if arr[i].action?.identifier == identifier { + return i + } + } + return nil + } } diff --git a/Sources/ProHUD/Toast/ToastDefaultLayout.swift b/Sources/ProHUD/Toast/ToastDefaultLayout.swift index e361a6b..110a96a 100644 --- a/Sources/ProHUD/Toast/ToastDefaultLayout.swift +++ b/Sources/ProHUD/Toast/ToastDefaultLayout.swift @@ -13,7 +13,10 @@ extension Toast: DefaultLayout { return config } - func reloadDataByDefault() { + func reloadData(animated: Bool) { + if self.cfg.customReloadData?(self) == true { + return + } loadContentViewIfNeeded() loadContentMaskViewIfNeeded() guard customView == nil else {