diff --git a/PHDemo/PHDemo.xcodeproj/xcshareddata/xcschemes/PHDemo.xcscheme b/PHDemo/PHDemo.xcodeproj/xcshareddata/xcschemes/PHDemo.xcscheme
new file mode 100644
index 0000000..f25f63e
--- /dev/null
+++ b/PHDemo/PHDemo.xcodeproj/xcshareddata/xcschemes/PHDemo.xcscheme
@@ -0,0 +1,77 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/PHDemo/PHDemo/DemoCapsuleVC.swift b/PHDemo/PHDemo/DemoCapsuleVC.swift
index e8c8127..8bf9bc4 100644
--- a/PHDemo/PHDemo/DemoCapsuleVC.swift
+++ b/PHDemo/PHDemo/DemoCapsuleVC.swift
@@ -84,15 +84,15 @@ class DemoCapsuleVC: ListVC {
}
}
- list.add(title: "不同位置、不同动画") { section in
- section.add(title: "顶部,默认滑入") {
- Capsule(.info("一条简短的消息"))
+ list.add(title: "不同位置、不同动画,队列推送") { section in
+ section.add(title: "顶部,默认动画") {
+ Capsule(.info("一条简短的消息").queuedPush(true).duration(1))
}
- section.add(title: "中间,默认缩放") {
- Capsule(.middle.info("一条简短的消息"))
+ section.add(title: "中间,默认动画") {
+ Capsule(.middle.queuedPush(true).info("一条简短的消息").duration(2))
}
section.add(title: "中间,黑底白字,透明渐变") {
- Capsule(.middle.info("一条简短的消息")) { capsule in
+ Capsule(.middle.queuedPush(true).info("一条简短的消息").duration(1)) { capsule in
capsule.config.tintColor = .white
capsule.config.cardCornerRadius = 8
capsule.config.contentViewMask { mask in
@@ -119,7 +119,7 @@ class DemoCapsuleVC: ListVC {
}
}
section.add(title: "底部,渐变背景,默认回弹滑入") {
- Capsule(.bottom.enter("点击进入")) { capsule in
+ Capsule(.bottom.queuedPush(true).enter("点击进入").duration(1)) { capsule in
capsule.config.tintColor = .white
capsule.config.cardEdgeInsets = .init(top: 12, left: 20, bottom: 12, right: 20)
capsule.config.customTextLabel { label in
@@ -146,6 +146,25 @@ class DemoCapsuleVC: ListVC {
}
}
}
+ list.add(title: "lazy push") { section in
+ section.add(title: "id:1, text:1") {
+ Capsule(.test1("111:111"))
+ }
+ section.add(title: "id:1, text:2") {
+ Capsule(.test1("111:222"))
+ }
+ section.add(title: "id:2, text:1") {
+ Capsule(.test2("222:111"))
+ }
+ section.add(title: "id:2, text:2") {
+ Capsule(.test2("222:222"))
+ }
+
+ section.add(title: "id:2, text:2") {
+ Capsule(.test2("222:222"))
+ Capsule(.test2("222:111"))
+ }
+ }
}
}
@@ -179,4 +198,22 @@ extension CapsuleViewModel {
.message(text)
}
+ static func test1(_ text: String) -> CapsuleViewModel {
+ .identifier("id:1")
+ .icon(.init(systemName: "video.circle.fill"))
+ .tintColor(.systemGreen)
+ .duration(1)
+ .queuedPush(true)
+ .message(text)
+ }
+
+ static func test2(_ text: String) -> CapsuleViewModel {
+ .identifier("id:2")
+ .icon(.init(systemName: "mic.circle.fill"))
+ .tintColor(.systemOrange)
+ .duration(1)
+ .queuedPush(true)
+ .message(text)
+ }
+
}
diff --git a/PHDemo/PHDemo/DemoToastVC.swift b/PHDemo/PHDemo/DemoToastVC.swift
index e84f7e9..5b689a7 100644
--- a/PHDemo/PHDemo/DemoToastVC.swift
+++ b/PHDemo/PHDemo/DemoToastVC.swift
@@ -106,7 +106,7 @@ class DemoToastVC: ListVC {
}
}
section.add(title: "图标 + 一段长文本") {
- Toast(.note.message(message))
+ Toast(.note.message(message).duration(1))
}
section.add(title: "网络图标 + 一段文本") {
Toast(.message("这是网络图标").icon(.init(string: "https://xaoxuu.com/assets/xaoxuu/avatar/rect-256@2x.png")))
@@ -167,7 +167,7 @@ class DemoToastVC: ListVC {
section.add(title: "禁止手势移除") {
let title = "这条消息很重要"
let message = "向上滑动将不会移除消息,您必须手动处理,用于重要但非阻塞性的事件。(通过代码处理或者在点击事件处理)"
- Toast(.warning.title(title).message(message)) { toast in
+ Toast(.warning.title(title).message(message).duration(.infinity)) { toast in
toast.isRemovable = false
toast.onTapped { toast in
toast.pop()
diff --git a/Sources/ProHUD/Alert/AlertConfiguration.swift b/Sources/ProHUD/Alert/AlertConfiguration.swift
index a3595a1..c02e8a8 100644
--- a/Sources/ProHUD/Alert/AlertConfiguration.swift
+++ b/Sources/ProHUD/Alert/AlertConfiguration.swift
@@ -30,8 +30,8 @@ public class AlertConfiguration: CommonConfiguration {
customBackgroundViewMask = callback
}
- override var animateDurationForBuildInByDefault: CGFloat {
- animateDurationForBuildIn ?? 0.6
+ override var animateDurationForBuildOutByDefault: CGFloat {
+ animateDurationForBuildOut ?? 0.2
}
}
diff --git a/Sources/ProHUD/Alert/AlertDefaultLayout.swift b/Sources/ProHUD/Alert/AlertDefaultLayout.swift
index d0c3c2a..5b4032e 100644
--- a/Sources/ProHUD/Alert/AlertDefaultLayout.swift
+++ b/Sources/ProHUD/Alert/AlertDefaultLayout.swift
@@ -124,13 +124,6 @@ extension AlertTarget: DefaultLayout {
}
}
- func updateTimeoutDuration() {
- // 设置持续时间
- vm?.timeoutHandler = DispatchWorkItem(block: { [weak self] in
- self?.pop()
- })
- }
-
}
extension AlertTarget {
diff --git a/Sources/ProHUD/Alert/AlertManager.swift b/Sources/ProHUD/Alert/AlertManager.swift
index c3c84d0..a356cda 100644
--- a/Sources/ProHUD/Alert/AlertManager.swift
+++ b/Sources/ProHUD/Alert/AlertManager.swift
@@ -16,7 +16,7 @@ extension AlertTarget {
return
}
setDefaultAxis()
- view.transform = .init(scaleX: 1.2, y: 1.2)
+ view.transform = .init(scaleX: 1.12, y: 1.12)
view.alpha = 0
navEvents[.onViewWillAppear]?(self)
window.vc.addChild(self)
@@ -33,6 +33,7 @@ extension AlertTarget {
window.backgroundView.alpha = 1
} completion: { done in
self.navEvents[.onViewDidAppear]?(self)
+ self.updateTimeoutDuration()
}
window.alerts.append(self)
AlertTarget.updateAlertsLayout(alerts: window.alerts)
@@ -42,9 +43,9 @@ extension AlertTarget {
navEvents[.onViewWillDisappear]?(self)
AlertTarget.removeAlert(alert: self)
let duration = config.animateDurationForBuildOut ?? config.animateDurationForBuildOutByDefault
- UIView.animateEaseOut(duration: duration) {
+ UIView.animateLinear(duration: duration) {
self.view.alpha = 0
- self.view.transform = .init(scaleX: 1.08, y: 1.08)
+ self.view.transform = .init(scaleX: 1.05, y: 1.05)
} completion: { done in
self.view.removeFromSuperview()
self.removeFromParent()
@@ -55,7 +56,7 @@ extension AlertTarget {
let count = window.alerts.count
if count == 0 {
AppContext.alertWindow[windowScene] = nil
- UIView.animateEaseOut(duration: duration) {
+ UIView.animateLinear(duration: duration) {
window.backgroundView.alpha = 0
} completion: { done in
// 这里设置一下window属性,会使window的生命周期被延长到此处,即动画执行过程中window不会被提前释放
@@ -74,6 +75,13 @@ extension AlertTarget {
}
}
+ func updateTimeoutDuration() {
+ // 设置持续时间
+ vm?.timeoutHandler = DispatchWorkItem(block: { [weak self] in
+ self?.pop()
+ })
+ }
+
}
// MARK: - layout
diff --git a/Sources/ProHUD/Alert/AlertWindow.swift b/Sources/ProHUD/Alert/AlertWindow.swift
index ec2e6f0..bd09c7a 100644
--- a/Sources/ProHUD/Alert/AlertWindow.swift
+++ b/Sources/ProHUD/Alert/AlertWindow.swift
@@ -36,6 +36,6 @@ class AlertWindow: Window {
extension AlertTarget {
var attachedWindow: AlertWindow? {
- view.window as? AlertWindow
+ view.window as? AlertWindow ?? AppContext.current?.alertWindow
}
}
diff --git a/Sources/ProHUD/Capsule/CapsuleConfiguration.swift b/Sources/ProHUD/Capsule/CapsuleConfiguration.swift
index 608e3a7..ff42e1e 100644
--- a/Sources/ProHUD/Capsule/CapsuleConfiguration.swift
+++ b/Sources/ProHUD/Capsule/CapsuleConfiguration.swift
@@ -35,11 +35,11 @@ public class CapsuleConfiguration: CommonConfiguration {
override var cardMaxHeightByDefault: CGFloat { cardMaxHeight ?? 120 }
override var animateDurationForBuildInByDefault: CGFloat {
- animateDurationForBuildIn ?? 0.8
+ animateDurationForBuildIn ?? 0.64
}
override var animateDurationForBuildOutByDefault: CGFloat {
- animateDurationForBuildOut ?? 0.8
+ animateDurationForBuildOut ?? 0.32
}
var animateBuildIn: CustomAnimateHandler?
diff --git a/Sources/ProHUD/Capsule/CapsuleDefaultLayout.swift b/Sources/ProHUD/Capsule/CapsuleDefaultLayout.swift
index 05aa75b..bf0bc11 100644
--- a/Sources/ProHUD/Capsule/CapsuleDefaultLayout.swift
+++ b/Sources/ProHUD/Capsule/CapsuleDefaultLayout.swift
@@ -79,17 +79,6 @@ extension CapsuleTarget: DefaultLayout {
}
- private func updateTimeoutDuration() {
- // 为空时使用默认规则
- if vm?.duration == nil {
- vm?.duration = config.defaultDuration
- }
- // 设置持续时间
- vm?.timeoutHandler = DispatchWorkItem(block: { [weak self] in
- self?.pop()
- })
- }
-
private func setupImageView() {
// 移除动画
stopRotate(animateLayer)
diff --git a/Sources/ProHUD/Capsule/CapsuleManager.swift b/Sources/ProHUD/Capsule/CapsuleManager.swift
index 55e9a1f..889dd42 100644
--- a/Sources/ProHUD/Capsule/CapsuleManager.swift
+++ b/Sources/ProHUD/Capsule/CapsuleManager.swift
@@ -11,17 +11,38 @@ extension CapsuleTarget {
@objc open func push() {
guard CapsuleConfiguration.isEnabled else { return }
+ guard let windowScene = preferredWindowScene ?? AppContext.windowScene else { return }
+ if windowScene != AppContext.windowScene {
+ AppContext.windowScene = windowScene
+ }
+
let isNew: Bool
let window: CapsuleWindow
let position = vm?.position ?? .top
- if let w = AppContext.current?.capsuleWindows[position] {
- isNew = false
- window = w
- } else {
- window = CapsuleWindow(capsule: self)
- isNew = true
+ if AppContext.capsuleWindows[windowScene] == nil {
+ AppContext.capsuleWindows[windowScene] = [:]
}
+ var windows = AppContext.capsuleWindows[windowScene] ?? [:]
+ if let w = windows[position], w.isHidden == false {
+ // 此时同一位置已有capsule在显示
+ if vm?.queuedPush == true {
+ // 加入队列
+ self.preferredWindowScene = windowScene
+ AppContext.capsuleInQueue.append(self)
+ return
+ } else {
+ // 直接覆盖
+ isNew = false
+ window = w
+ }
+ } else {
+ // 空闲状态下推送一个新的
+ isNew = true
+ window = CapsuleWindow(capsule: self)
+ windows[position] = nil
+ }
+
// frame
let cardEdgeInsetsByDefault = config.cardEdgeInsetsByDefault
view.layoutIfNeeded()
@@ -53,22 +74,22 @@ extension CapsuleTarget {
view.layer.cornerRadiusWithContinuous = config.cardCornerRadiusByDefault
window.rootViewController = self // 此时toast.view.frame.size会自动更新为window.frame.size
- if let s = AppContext.windowScene {
- if AppContext.capsuleWindows[s] == nil {
- AppContext.capsuleWindows[s] = [:]
- }
- AppContext.capsuleWindows[s]?[position] = window
- }
+
+ AppContext.capsuleWindows[windowScene]?[position] = window
+
navEvents[.onViewWillAppear]?(self)
- // 更新toast防止重叠
- ToastWindow.updateToastWindowsLayout()
+ if position == .top {
+ // 更新toast防止重叠
+ ToastWindow.updateToastWindowsLayout()
+ }
+ func completion() {
+ self.navEvents[.onViewDidAppear]?(self)
+ self.updateTimeoutDuration()
+ }
if isNew {
window.isHidden = false
- func completion() {
- self.navEvents[.onViewDidAppear]?(self)
- }
if let animateBuildIn = config.animateBuildIn {
animateBuildIn(window, completion)
} else {
@@ -82,16 +103,14 @@ extension CapsuleTarget {
completion()
}
case .middle:
- let d0 = duration * 0.2
- let d1 = duration
- window.transform = .init(scaleX: 0.001, y: 0.001)
- window.alpha = 0
- UIView.animate(withDuration: duration, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.5) {
+ window.transform = .init(translationX: 0, y: 24)
+ UIView.animate(withDuration: duration, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 0.5) {
window.transform = .identity
} completion: { done in
completion()
}
- UIView.animate(withDuration: duration * 0.4, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1) {
+ window.alpha = 0
+ UIView.animateLinear(duration: duration * 0.5) {
window.alpha = 1
}
case .bottom:
@@ -103,8 +122,6 @@ extension CapsuleTarget {
completion()
}
}
-
-
}
} else {
view.layoutIfNeeded()
@@ -112,7 +129,7 @@ extension CapsuleTarget {
window.frame = newFrame
window.layoutIfNeeded()
} completion: { done in
- self.navEvents[.onViewDidAppear]?(self)
+ completion()
}
}
@@ -120,11 +137,13 @@ extension CapsuleTarget {
@objc open func pop() {
guard let window = attachedWindow, let windowScene = windowScene else { return }
- AppContext.capsuleWindows[windowScene]?[vm?.position ?? .top] = nil
+ let position = vm?.position ?? .top
+ AppContext.capsuleWindows[windowScene]?[position] = nil
navEvents[.onViewWillDisappear]?(self)
- // 更新toast防止重叠
- ToastWindow.updateToastWindowsLayout()
-
+ if position == .top {
+ // 更新toast防止重叠
+ ToastWindow.updateToastWindowsLayout()
+ }
func completion() {
window.isHidden = true
window.transform = .identity
@@ -135,31 +154,37 @@ extension CapsuleTarget {
} else {
let duration = config.animateDurationForBuildOutByDefault
let oldFrame = window.frame
- switch vm?.position {
- case .top, .none:
- UIView.animateEaseOut(duration: duration) {
+ switch position {
+ case .top:
+ UIView.animateEaseIn(duration: duration) {
window.transform = .init(translationX: 0, y: -oldFrame.maxY - 20)
} completion: { done in
completion()
}
case .middle:
- UIView.animate(withDuration: duration * 0.6, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 0.5) {
- window.transform = .init(scaleX: 0.001, y: 0.001)
+ let duration = config.animateDurationForBuildInByDefault * 1
+ UIView.animateEaseIn(duration: duration) {
+ window.transform = .init(translationX: 0, y: -24)
} completion: { done in
completion()
}
- UIView.animate(withDuration: duration * 0.4, delay: duration * 0.2, usingSpringWithDamping: 1, initialSpringVelocity: 0.5) {
+ UIView.animateLinear(duration: duration * 0.5, delay: duration * 0.3) {
window.alpha = 0
}
case .bottom:
let offsetY = AppContext.appBounds.height - oldFrame.maxY + 100
- UIView.animate(withDuration: duration, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 0) {
+ UIView.animateEaseIn(duration: duration) {
window.transform = .init(translationX: 0, y: offsetY)
} completion: { done in
completion()
}
}
-
+ }
+ if let next = AppContext.capsuleInQueue.first(where: { $0.preferredWindowScene == windowScene && $0.vm?.position == position }) {
+ AppContext.capsuleInQueue.removeAll(where: { $0 == next })
+ DispatchQueue.main.asyncAfter(deadline: .now() + config.animateDurationForBuildOutByDefault * 0.8) {
+ next.push()
+ }
}
}
@@ -174,4 +199,15 @@ extension CapsuleTarget {
}
}
+ func updateTimeoutDuration() {
+ // 为空时使用默认规则
+ if vm?.duration == nil {
+ vm?.duration = config.defaultDuration
+ }
+ // 设置持续时间
+ vm?.timeoutHandler = DispatchWorkItem(block: { [weak self] in
+ self?.pop()
+ })
+ }
+
}
diff --git a/Sources/ProHUD/Capsule/CapsuleProvider.swift b/Sources/ProHUD/Capsule/CapsuleProvider.swift
index 161fc4a..f4e57f0 100644
--- a/Sources/ProHUD/Capsule/CapsuleProvider.swift
+++ b/Sources/ProHUD/Capsule/CapsuleProvider.swift
@@ -68,7 +68,9 @@ open class CapsuleProvider: HUDProvider {
/// - Parameter identifier: 唯一标识符
/// - Returns: HUD实例
@discardableResult public static func find(identifier: String, update handler: ((_ capsule: CapsuleTarget) -> Void)? = nil) -> [CapsuleTarget] {
- let arr = AppContext.capsuleWindows.values.flatMap({ $0.values }).compactMap({ $0.capsule }).filter({ $0.identifier == identifier })
+ let allPositions = AppContext.capsuleWindows.values.flatMap({ $0.values })
+ let allCapsules = allPositions.compactMap({ $0.capsule })
+ let arr = (allCapsules + AppContext.capsuleInQueue).filter({ $0.identifier == identifier })
if let handler = handler {
arr.forEach({ $0.update(handler: handler) })
}
diff --git a/Sources/ProHUD/Capsule/CapsuleViewModel.swift b/Sources/ProHUD/Capsule/CapsuleViewModel.swift
index 5c5157b..518eacb 100644
--- a/Sources/ProHUD/Capsule/CapsuleViewModel.swift
+++ b/Sources/ProHUD/Capsule/CapsuleViewModel.swift
@@ -17,24 +17,38 @@ import UIKit
@objc public var position: Position = .top
- public func position(position: Position) -> Self {
+ // Capsule 在一个位置最多只显示一个实例
+ // queuedPush: false 如果已有就直接覆盖
+ // queuedPush: true 如果已有就排队等待
+ @objc public var queuedPush: Bool = false
+
+}
+
+public extension CapsuleViewModel {
+
+ func position(_ position: Position) -> Self {
self.position = position
return self
}
- public static var top: Self {
+ static var top: Self {
let obj = Self.init()
obj.position = .top
return obj
}
- public static var middle: Self {
+ static var middle: Self {
let obj = Self.init()
obj.position = .middle
return obj
}
- public static var bottom: Self {
+ static var bottom: Self {
let obj = Self.init()
obj.position = .bottom
return obj
}
+ func queuedPush(_ queuedPush: Bool) -> Self {
+ self.queuedPush = queuedPush
+ return self
+ }
+
}
diff --git a/Sources/ProHUD/Capsule/CapsuleWindow.swift b/Sources/ProHUD/Capsule/CapsuleWindow.swift
index fea0a79..2079b63 100644
--- a/Sources/ProHUD/Capsule/CapsuleWindow.swift
+++ b/Sources/ProHUD/Capsule/CapsuleWindow.swift
@@ -27,7 +27,7 @@ class CapsuleWindow: Window {
windowLevel = .phCapsuleBottom
}
frame = .init(x: 0, y: 0, width: 128, height: 48)
- isHidden = false
+ isHidden = true
}
required init?(coder: NSCoder) {
diff --git a/Sources/ProHUD/Core/Controllers/BaseController.swift b/Sources/ProHUD/Core/Controllers/BaseController.swift
index 9564294..e1bcea0 100644
--- a/Sources/ProHUD/Core/Controllers/BaseController.swift
+++ b/Sources/ProHUD/Core/Controllers/BaseController.swift
@@ -9,6 +9,9 @@ import UIKit
open class BaseController: UIViewController {
+ /// 需要显示到那个UIWindowScene上
+ var preferredWindowScene: UIWindowScene?
+
/// ID标识
public var identifier = String(Date().timeIntervalSince1970)
@@ -23,6 +26,7 @@ open class BaseController: UIViewController {
open var customView: UIView?
public internal(set) var isViewDisplayed = false
+
/// 按钮事件
var buttonEvents = [UIView: () -> Void]()
diff --git a/Sources/ProHUD/Core/Protocols/Provider.swift b/Sources/ProHUD/Core/Protocols/Provider.swift
index 134eb65..4eb8f9f 100644
--- a/Sources/ProHUD/Core/Protocols/Provider.swift
+++ b/Sources/ProHUD/Core/Protocols/Provider.swift
@@ -32,9 +32,7 @@ open class HUDProvider: NSOb
}
var t = Target()
initializer(t)
- DispatchQueue.main.async {
- t.push()
- }
+ t.push()
}
}
diff --git a/Sources/ProHUD/Core/Utils/AppContext.swift b/Sources/ProHUD/Core/Utils/AppContext.swift
index 88c1230..34e2159 100644
--- a/Sources/ProHUD/Core/Utils/AppContext.swift
+++ b/Sources/ProHUD/Core/Utils/AppContext.swift
@@ -37,6 +37,7 @@ public struct AppContext {
static var alertWindow: [UIWindowScene: AlertWindow] = [:]
static var sheetWindows: [UIWindowScene: [SheetWindow]] = [:]
static var capsuleWindows: [UIWindowScene: [CapsuleViewModel.Position: CapsuleWindow]] = [:]
+ static var capsuleInQueue: [CapsuleTarget] = []
static var current: AppContext? {
guard let windowScene = windowScene else { return nil }
@@ -123,5 +124,8 @@ extension AppContext {
var capsuleWindows: [CapsuleViewModel.Position: CapsuleWindow] {
Self.capsuleWindows[windowScene] ?? [:]
}
+ var alertWindow: AlertWindow? {
+ Self.alertWindow[windowScene]
+ }
}
diff --git a/Sources/ProHUD/Core/Utils/ViewExts.swift b/Sources/ProHUD/Core/Utils/ViewExts.swift
index 092e4bd..e61fb9f 100644
--- a/Sources/ProHUD/Core/Utils/ViewExts.swift
+++ b/Sources/ProHUD/Core/Utils/ViewExts.swift
@@ -9,8 +9,14 @@ import UIKit
extension UIView {
+ static func animateLinear(duration: TimeInterval, delay: TimeInterval = 0, animations: @escaping () -> Void, completion: ((_ done: Bool) -> Void)? = nil) {
+ animate(withDuration: duration, delay: delay, options: [.allowUserInteraction], animations: animations, completion: completion)
+ }
+ static func animateEaseIn(duration: TimeInterval, animations: @escaping () -> Void, completion: ((_ done: Bool) -> Void)? = nil) {
+ animate(withDuration: duration, delay: 0, options: [.allowUserInteraction, .curveEaseIn], animations: animations, completion: completion)
+ }
static func animateEaseOut(duration: TimeInterval, animations: @escaping () -> Void, completion: ((_ done: Bool) -> Void)? = nil) {
- animate(withDuration: duration, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 0.75, options: [.allowUserInteraction, .curveEaseOut], animations: animations, completion: completion)
+ animate(withDuration: duration, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 0.5, options: [.allowUserInteraction, .curveEaseOut], animations: animations, completion: completion)
}
}
diff --git a/Sources/ProHUD/Sheet/SheetConfiguration.swift b/Sources/ProHUD/Sheet/SheetConfiguration.swift
index 58665df..0e7b4dd 100644
--- a/Sources/ProHUD/Sheet/SheetConfiguration.swift
+++ b/Sources/ProHUD/Sheet/SheetConfiguration.swift
@@ -51,11 +51,11 @@ public class SheetConfiguration: CommonConfiguration {
override var cardMaxHeightByDefault: CGFloat { cardMaxHeight ?? (AppContext.appBounds.height - 50) }
override var animateDurationForBuildInByDefault: CGFloat {
- animateDurationForBuildIn ?? 0.5
+ animateDurationForBuildIn ?? 0.38
}
override var animateDurationForBuildOutByDefault: CGFloat {
- animateDurationForBuildOut ?? 0.5
+ animateDurationForBuildOut ?? 0.24
}
override var cardCornerRadiusByDefault: CGFloat { cardCornerRadius ?? 32 }
diff --git a/Sources/ProHUD/Sheet/SheetDefaultLayout.swift b/Sources/ProHUD/Sheet/SheetDefaultLayout.swift
index 6b34277..8feafdb 100644
--- a/Sources/ProHUD/Sheet/SheetDefaultLayout.swift
+++ b/Sources/ProHUD/Sheet/SheetDefaultLayout.swift
@@ -44,18 +44,16 @@ extension SheetTarget: DefaultLayout {
// mask
loadContentMaskViewIfNeeded()
// layout
+ let windowWidth = AppContext.appBounds.width
let maxWidth = config.cardMaxWidthByDefault
- var width = AppContext.appBounds.width - config.windowEdgeInset * 2
- if width > maxWidth {
- // landscape iPhone or iPad
- width = maxWidth
- }
+ let autoWidth = windowWidth - config.windowEdgeInset * 2
+ let width = min(autoWidth, maxWidth)
contentView.snp.remakeConstraints { make in
if config.isFullScreen {
make.edges.equalToSuperview()
} else {
make.centerX.equalToSuperview()
- if UIDevice.current.userInterfaceIdiom == .pad && width >= maxWidth {
+ if UIDevice.current.userInterfaceIdiom == .pad && width < autoWidth - 40 {
// iPad且窗口宽度较宽时居中弹出
make.centerY.equalToSuperview()
} else {
diff --git a/Sources/ProHUD/Sheet/SheetManager.swift b/Sources/ProHUD/Sheet/SheetManager.swift
index b726ac0..9fbfedd 100644
--- a/Sources/ProHUD/Sheet/SheetManager.swift
+++ b/Sources/ProHUD/Sheet/SheetManager.swift
@@ -27,6 +27,7 @@ extension SheetTarget {
setContextWindows(windows)
}
if isNew {
+ _translateOut()
navEvents[.onViewWillAppear]?(self)
window.sheet.translateIn { [weak self] in
guard let self = self else { return }
@@ -89,7 +90,7 @@ extension SheetTarget {
}
func translateOut(completion: (() -> Void)?) {
- UIView.animateEaseOut(duration: config.animateDurationForBuildOutByDefault) {
+ UIView.animateLinear(duration: config.animateDurationForBuildOutByDefault) {
self._translateOut()
if self.config.stackDepthEffect {
AppContext.appWindow?.transform = .identity
diff --git a/Sources/ProHUD/Sheet/SheetTarget.swift b/Sources/ProHUD/Sheet/SheetTarget.swift
index b83287a..1e237da 100644
--- a/Sources/ProHUD/Sheet/SheetTarget.swift
+++ b/Sources/ProHUD/Sheet/SheetTarget.swift
@@ -20,7 +20,6 @@ open class SheetTarget: BaseController, HUDTargetType {
public lazy var backgroundView: UIView = {
let v = UIView()
v.backgroundColor = .init(white: 0, alpha: 0.5)
- v.alpha = 0
return v
}()
@@ -64,8 +63,6 @@ open class SheetTarget: BaseController, HUDTargetType {
reloadData(animated: false)
- _translateOut()
-
navEvents[.onViewDidLoad]?(self)
}
diff --git a/Sources/ProHUD/Toast/ToastConfiguration.swift b/Sources/ProHUD/Toast/ToastConfiguration.swift
index d9f34f5..4bba30d 100644
--- a/Sources/ProHUD/Toast/ToastConfiguration.swift
+++ b/Sources/ProHUD/Toast/ToastConfiguration.swift
@@ -42,11 +42,11 @@ public class ToastConfiguration: CommonConfiguration {
}
override var animateDurationForBuildInByDefault: CGFloat {
- animateDurationForBuildIn ?? 0.8
+ animateDurationForBuildIn ?? 0.64
}
override var animateDurationForBuildOutByDefault: CGFloat {
- animateDurationForBuildIn ?? 0.8
+ animateDurationForBuildIn ?? 0.32
}
}
diff --git a/Sources/ProHUD/Toast/ToastDefaultLayout.swift b/Sources/ProHUD/Toast/ToastDefaultLayout.swift
index fcc3d40..706fd25 100644
--- a/Sources/ProHUD/Toast/ToastDefaultLayout.swift
+++ b/Sources/ProHUD/Toast/ToastDefaultLayout.swift
@@ -134,17 +134,6 @@ extension ToastTarget {
}
}
- private func updateTimeoutDuration() {
- // 为空时使用默认规则
- if vm?.duration == nil {
- vm?.duration = config.defaultDuration
- }
- // 设置持续时间
- vm?.timeoutHandler = DispatchWorkItem(block: { [weak self] in
- self?.pop()
- })
- }
-
func setupImageView() {
// 移除动画
stopRotate(animateLayer)
diff --git a/Sources/ProHUD/Toast/ToastManager.swift b/Sources/ProHUD/Toast/ToastManager.swift
index 52b31f7..3c02513 100644
--- a/Sources/ProHUD/Toast/ToastManager.swift
+++ b/Sources/ProHUD/Toast/ToastManager.swift
@@ -66,16 +66,21 @@ extension ToastTarget {
setContextWindows(windows)
}
ToastWindow.updateToastWindowsLayout(windows: windows)
+
+ func completion() {
+ self.navEvents[.onViewDidAppear]?(self)
+ self.updateTimeoutDuration()
+ }
if isNew {
window.transform = .init(translationX: 0, y: -window.frame.maxY)
UIView.animateEaseOut(duration: config.animateDurationForBuildInByDefault) {
window.transform = .identity
} completion: { done in
- self.navEvents[.onViewDidAppear]?(self)
+ completion()
}
} else {
view.layoutIfNeeded()
- self.navEvents[.onViewDidAppear]?(self)
+ completion()
}
}
@@ -94,7 +99,7 @@ extension ToastTarget {
}
vm?.duration = nil
setContextWindows(windows)
- UIView.animateEaseOut(duration: config.animateDurationForBuildOutByDefault) {
+ UIView.animateLinear(duration: config.animateDurationForBuildOutByDefault) {
window.transform = .init(translationX: 0, y: 0-20-window.maxY)
} completion: { done in
self.view.removeFromSuperview()
@@ -115,6 +120,17 @@ extension ToastTarget {
}
}
+ func updateTimeoutDuration() {
+ // 为空时使用默认规则
+ if vm?.duration == nil {
+ vm?.duration = config.defaultDuration
+ }
+ // 设置持续时间
+ vm?.timeoutHandler = DispatchWorkItem(block: { [weak self] in
+ self?.pop()
+ })
+ }
+
}
// MARK: - layout