From d45b08802482b8a785c2a13c8e13b32d70e19bea Mon Sep 17 00:00:00 2001 From: teaualune Date: Mon, 9 Feb 2026 13:59:58 +0800 Subject: [PATCH] feature: add more customize properties for SwiftUI ProgressHUD --- SwiftUI/Sources/ProgressHUD+Enums.swift | 1 + SwiftUI/Sources/ProgressHUD+Public.swift | 30 +++++++++++++++ SwiftUI/Sources/ProgressHUD.swift | 48 +++++++++++++++++++----- 3 files changed, 70 insertions(+), 9 deletions(-) diff --git a/SwiftUI/Sources/ProgressHUD+Enums.swift b/SwiftUI/Sources/ProgressHUD+Enums.swift index 0a905c8..7c76618 100644 --- a/SwiftUI/Sources/ProgressHUD+Enums.swift +++ b/SwiftUI/Sources/ProgressHUD+Enums.swift @@ -27,6 +27,7 @@ public enum AnimationType: CaseIterable { case circleRippleSingle case circleRotateChase case circleStrokeSpin + case custom case dualDotSidestep case horizontalBarScaling case horizontalDotScaling diff --git a/SwiftUI/Sources/ProgressHUD+Public.swift b/SwiftUI/Sources/ProgressHUD+Public.swift index 9032c92..9a6c3cb 100644 --- a/SwiftUI/Sources/ProgressHUD+Public.swift +++ b/SwiftUI/Sources/ProgressHUD+Public.swift @@ -83,6 +83,36 @@ public extension ProgressHUD { get { shared.colorError } set { shared.colorError = newValue } } + + static var backgroundMaterial: Material? { + get { shared.backgroundMaterial } + set { shared.backgroundMaterial = newValue } + } + + static var borderRadius: CGFloat { + get { shared.borderRadius } + set { shared.borderRadius = newValue } + } + + static var verticalSpacing: CGFloat { + get { shared.verticalSpacing } + set { shared.verticalSpacing = newValue } + } + + static var textMaxWidth: CGFloat { + get { shared.textMaxWidth } + set { shared.textMaxWidth = newValue } + } + + static var padding: EdgeInsets? { + get { shared.padding } + set { shared.padding = newValue } + } + + static var customAnimation: (() -> View)? { + get { shared.customAnimation } + set { shared.customAnimation = newValue } + } } // MARK: - Banner Configuration diff --git a/SwiftUI/Sources/ProgressHUD.swift b/SwiftUI/Sources/ProgressHUD.swift index c6c4444..e94a7c5 100644 --- a/SwiftUI/Sources/ProgressHUD.swift +++ b/SwiftUI/Sources/ProgressHUD.swift @@ -68,6 +68,13 @@ public class ProgressHUD { public var fontBannerTitle = Font.system(size: 16, weight: .semibold) public var fontBannerMessage = Font.system(size: 14) + public var backgroundMaterial: Material? = Material.regularMaterial + public var borderRadius: CGFloat = 10 + public var verticalSpacing: CGFloat = 10 + public var textMaxWidth: CGFloat = 180 + public var padding: EdgeInsets? + public var customAnimation: (() -> View)? + var interaction = true var dismissTask: Task? var dismissAnimTask: Task? @@ -126,7 +133,7 @@ public struct ProgressHUDView: View { private var hudContent: some View { let size = hud.mediaSize + 40 - VStack(spacing: 10) { + VStack(spacing: hud.verticalSpacing) { if !shouldHideMedia { mediaView .frame(width: hud.mediaSize, height: hud.mediaSize) @@ -137,24 +144,41 @@ public struct ProgressHUDView: View { .font(hud.fontStatus) .foregroundStyle(hud.colorStatus) .multilineTextAlignment(.center) - .frame(maxWidth: 180) + .frame(maxWidth: hud.textMaxWidth) .fixedSize(horizontal: false, vertical: true) } } - .padding(hasText ? 16 : 20) + .padding(padding) .frame(width: hasText ? nil : size, height: hasText ? nil : size) .fixedSize(horizontal: !hasText, vertical: true) .background { - RoundedRectangle(cornerRadius: 10) - .fill(hud.colorHUD) - .background { - RoundedRectangle(cornerRadius: 10) - .fill(.regularMaterial) + hudBackground.clipShape(RoundedRectangle(cornerRadius: hud.borderRadius)) + } + } + + @ViewBuilder + private var hudBackground: some View { + let hudBackground = RoundedRectangle(cornerRadius: hud.borderRadius) + .fill(hud.colorHUD) + .clipShape(RoundedRectangle(cornerRadius: hud.borderRadius)) + if let material = hud.backgroundMaterial { + hudBackground.background { + RoundedRectangle(cornerRadius: hud.borderRadius) + .fill(.regularMaterial) } - .clipShape(RoundedRectangle(cornerRadius: 10)) + } else { + hudBackground } } + private var padding: EdgeInsets { + if let hudPadding = hud.padding { + return hudPadding + } + let length: CGFloat = hasText ? 16 : 20 + return EdgeInsets(top: length, leading: length, bottom: length, trailing: length) + } + private var shouldHideMedia: Bool { if case .animation = hud.displayMode { return hud.animationType == .none @@ -232,6 +256,12 @@ public struct ProgressHUDView: View { CircleRotateChaseView() case .circleStrokeSpin: CircleStrokeSpinView() + case .custom: + if let customAnimation = hud.customAnimation { + AnyView(customAnimation()) + } else { + EmptyView() + } case .dualDotSidestep: DualDotSidestepView() case .horizontalBarScaling: