From 4ad50b651daff3084e3e60e7b81543793999b691 Mon Sep 17 00:00:00 2001 From: eladdekel Date: Mon, 25 May 2026 19:04:19 -0400 Subject: [PATCH] Add iOS 26 liquid glass support to Apple Music alert views Both AlertAppleMusic16View and AlertAppleMusic17View now auto-upgrade their background to a tinted UIGlassEffect on iOS 26+, falling back to the existing blur material on older versions. A new init parameter lets callers opt out and keep the classic blur on iOS 26. --- README.md | 50 +++++++------------ SPAlert.podspec | 17 ------- .../Views/AlertAppleMusic16View.swift | 29 ++++++++--- .../Views/AlertAppleMusic17View.swift | 23 +++++++-- 4 files changed, 61 insertions(+), 58 deletions(-) delete mode 100644 SPAlert.podspec diff --git a/README.md b/README.md index 31c5a29..c812ff1 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,6 @@ public enum AlertViewStyle { - [Installation](#installation) - [Swift Package Manager](#swift-package-manager) - - [CocoaPods](#cocoapods) - [SwiftUI](#swiftui) - [Present & Dismiss](#present--dismiss) - [Customisation](#customisation) @@ -56,31 +55,17 @@ Ready to use on iOS 13+. Supports iOS and visionOS. Working with `UIKit` and `Sw In Xcode go to Project -> Your Project Name -> `Package Dependencies` -> Tap _Plus_. Insert url: ``` -https://github.com/sparrowcode/AlertKit +https://github.com/eladdekel/AlertKit ``` or adding it to the `dependencies` of your `Package.swift`: ```swift dependencies: [ - .package(url: "https://github.com/sparrowcode/AlertKit", .upToNextMajor(from: "5.1.8")) + .package(url: "https://github.com/eladdekel/AlertKit", .upToNextMajor(from: "5.1.8")) ] ``` -### CocoaPods: - -This is an outdated way of doing things. I advise you to use [SPM](#swift-package-manager). However, I will continue to support Cocoapods for some time. - -
Cocoapods Installation - -[CocoaPods](https://cocoapods.org) is a dependency manager. For usage and installation instructions, visit their website. To integrate using CocoaPods, specify it in your `Podfile`: - -```ruby -pod 'SPAlert' -``` - -
- ### Manually If you prefer not to use any of dependency managers, you can integrate manually. Put `Sources/AlertKit` folder in your Xcode project. Make sure to enable `Copy items if needed` and `Create groups`. @@ -109,6 +94,21 @@ alertView.titleLabel.font = UIFont.systemFont(ofSize: 21) alertView.titleLabel.textColor = .white ``` +### Liquid Glass (iOS 26+) + +On iOS 26 and later, both `AlertAppleMusic16View` and `AlertAppleMusic17View` automatically upgrade their background to a tinted `UIGlassEffect`. On older iOS versions they fall back to the original blur material, so no caller changes are required. + +If you want to opt out and force the classic blur on iOS 26+, pass `forceNonGlass: true` at construction time: + +```swift +let alertView = AlertAppleMusic17View(title: "Added to Library", subtitle: nil, icon: .done, forceNonGlass: true) + +// also available on the iOS 16 style +let alertView16 = AlertAppleMusic16View(title: "Added to Library", subtitle: nil, icon: .done, forceNonGlass: true) +``` + +The flag must be set at init — the background effect is built during initialisation, so a property change afterwards would have no effect. + ## Present & Dismiss You can present and dismiss alerts manually via view. @@ -128,18 +128,6 @@ For dismiss all alerts that was presented: AlertKitAPI.dismissAllAlerts() ``` -## Apps Using - -

- - - - - - - - - -

+## Disclaimer -If you use a `AlertKit`, add your app via Pull Request. +This is a fork of sparrowcode's [AlertKit](https://github.com/sparrowcode/AlertKit) to support iOS 26's tinted glass. \ No newline at end of file diff --git a/SPAlert.podspec b/SPAlert.podspec deleted file mode 100644 index 9378b4e..0000000 --- a/SPAlert.podspec +++ /dev/null @@ -1,17 +0,0 @@ -Pod::Spec.new do |s| - - s.name = 'SPAlert' - s.version = '5.1.8' - s.summary = 'Native alert from Apple Music & Feedback. Contains Done, Heart & Message and other presets. Support SwiftUI.' - s.homepage = 'https://github.com/sparrowcode/AlertKit' - s.source = { :git => 'https://github.com/sparrowcode/AlertKit.git', :tag => s.version } - s.license = { :type => "MIT", :file => "LICENSE" } - s.author = { 'Sparrow Code' => 'hello@sparrowcode.io' } - - s.swift_version = '5.1' - s.ios.deployment_target = '13.0' - #s.tvos.deployment_target = '13.0' - - s.source_files = 'Sources/AlertKit/**/*.swift' - -end diff --git a/Sources/AlertKit/Views/AlertAppleMusic16View.swift b/Sources/AlertKit/Views/AlertAppleMusic16View.swift index b58062e..3ee4a4c 100644 --- a/Sources/AlertKit/Views/AlertAppleMusic16View.swift +++ b/Sources/AlertKit/Views/AlertAppleMusic16View.swift @@ -11,6 +11,8 @@ public class AlertAppleMusic16View: UIView, AlertViewProtocol { public let titleLabel: UILabel? public let subtitleLabel: UILabel? public let iconView: UIView? + + private let forceNonGlass: Bool public static var defaultContentColor = UIColor { trait in switch trait.userInterfaceStyle { @@ -26,23 +28,36 @@ public class AlertAppleMusic16View: UIView, AlertViewProtocol { fileprivate var completion: (()->Void)? = nil private lazy var backgroundView: UIVisualEffectView = { - let view: UIVisualEffectView = { + let effect: UIVisualEffect = { #if !os(tvOS) + if #available(iOS 26, *), !forceNonGlass { + let glass = UIGlassEffect() + glass.tintColor = UIColor { trait in + switch trait.userInterfaceStyle { + case .dark: return UIColor.white.withAlphaComponent(0.12) + default: return UIColor.black.withAlphaComponent(0.06) + } + } + return glass + } if #available(iOS 13.0, *) { - return UIVisualEffectView(effect: UIBlurEffect(style: .systemThickMaterial)) + return UIBlurEffect(style: .systemThickMaterial) } else { - return UIVisualEffectView(effect: UIBlurEffect(style: .light)) + return UIBlurEffect(style: .light) } #else - return UIVisualEffectView(effect: UIBlurEffect(style: .light)) + return UIBlurEffect(style: .light) #endif }() + let view = UIVisualEffectView(effect: effect) view.isUserInteractionEnabled = false return view }() - - public init(title: String? = nil, subtitle: String? = nil, icon: AlertIcon? = nil) { - + + public init(title: String? = nil, subtitle: String? = nil, icon: AlertIcon? = nil, forceNonGlass: Bool = false) { + + self.forceNonGlass = forceNonGlass + if let title = title { let label = UILabel() label.font = UIFont.preferredFont(forTextStyle: .title2, weight: .bold) diff --git a/Sources/AlertKit/Views/AlertAppleMusic17View.swift b/Sources/AlertKit/Views/AlertAppleMusic17View.swift index 6215da7..fe9de79 100644 --- a/Sources/AlertKit/Views/AlertAppleMusic17View.swift +++ b/Sources/AlertKit/Views/AlertAppleMusic17View.swift @@ -12,6 +12,8 @@ public class AlertAppleMusic17View: UIView, AlertViewProtocol, AlertViewInternal public let titleLabel: UILabel? public let subtitleLabel: UILabel? public let iconView: UIView? + + private let forceNonGlass: Bool public static var defaultContentColor = UIColor { trait in #if os(visionOS) @@ -38,14 +40,29 @@ public class AlertAppleMusic17View: UIView, AlertViewProtocol, AlertViewInternal hostView.isUserInteractionEnabled = false return hostView #else - let view = UIVisualEffectView(effect: UIBlurEffect(style: .systemMaterial)) + let effect: UIVisualEffect + if #available(iOS 26, *), !forceNonGlass { + let glass = UIGlassEffect() + glass.tintColor = UIColor { trait in + switch trait.userInterfaceStyle { + case .dark: return UIColor.white.withAlphaComponent(0.12) + default: return UIColor.black.withAlphaComponent(0.06) + } + } + effect = glass + } else { + effect = UIBlurEffect(style: .systemMaterial) + } + let view = UIVisualEffectView(effect: effect) view.isUserInteractionEnabled = false return view #endif }() - public init(title: String? = nil, subtitle: String? = nil, icon: AlertIcon? = nil) { - + public init(title: String? = nil, subtitle: String? = nil, icon: AlertIcon? = nil, forceNonGlass: Bool = false) { + + self.forceNonGlass = forceNonGlass + if let title = title { let label = UILabel() label.font = UIFont.preferredFont(forTextStyle: .body, weight: .semibold, addPoints: -2)