Skip to content

Commit b2f83ec

Browse files
committed
added glass effect
1 parent 405baa5 commit b2f83ec

File tree

2 files changed

+77
-0
lines changed

2 files changed

+77
-0
lines changed

Sources/VisualEffectView/VisualEffectView+SwiftUI.swift

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,38 @@ public struct VisualEffect: UIViewRepresentable {
5353
*/
5454
let scale: CGFloat
5555

56+
public enum BlurStyle: Equatable {
57+
case system(UIBlurEffect.Style)
58+
case custom(radius: CGFloat, saturation: CGFloat)
59+
}
60+
61+
@available(iOS 26.0, *)
62+
public enum GlassStyle: Equatable {
63+
case regular
64+
case clear
65+
case prominent
66+
67+
var value: UIGlassEffect.Style {
68+
switch self {
69+
case .regular: .regular
70+
case .clear: .clear
71+
case .prominent: .prominent
72+
}
73+
}
74+
}
75+
76+
public enum VisualEffectStyle: Equatable {
77+
case blur(BlurStyle)
78+
@available(iOS 26.0, *)
79+
case glass(GlassStyle)
80+
}
81+
82+
@available(iOS 26.0, *)
83+
public var glassTintColor: UIColor?
84+
85+
@available(iOS 26.0, *)
86+
public var isGlassInteractive: Bool
87+
5688
/**
5789
Initializes a `VisualEffect` view with the specified parameters.
5890

@@ -70,6 +102,13 @@ public struct VisualEffect: UIViewRepresentable {
70102
self.saturation = saturation
71103
self.scale = scale
72104
}
105+
106+
@available(iOS 26.0, *)
107+
public init(glass: GlassStyle, tint: UIColor? = nil, interactive: Bool = false) {
108+
self.glass = glass
109+
self.tint = tint
110+
self.interactive = interactive
111+
}
73112

74113
public func makeUIView(context: Context) -> VisualEffectView {
75114
let view = VisualEffectView()

Sources/VisualEffectView/VisualEffectView.swift

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,27 @@ open class VisualEffectView: UIVisualEffectView {
8383
get { return _value(forKey: .scale) ?? 1.0 }
8484
set { _setValue(newValue, forKey: .scale) }
8585
}
86+
87+
public var style: VisualEffectStyle = .none {
88+
didSet {
89+
switch style {
90+
91+
case .none:
92+
effectView.effect = nil
93+
94+
case .blur(let blur):
95+
effectView.effect = makeBlurEffect(from: blur)
96+
97+
case .glass(let glass):
98+
if #available(iOS 26.0, *) {
99+
effectView.effect = makeGlassEffect(from: glass)
100+
} else {
101+
// graceful fallback
102+
effectView.effect = UIBlurEffect(style: .systemThinMaterial)
103+
}
104+
}
105+
}
106+
}
86107

87108
// MARK: - Initialization
88109

@@ -121,3 +142,20 @@ private extension VisualEffectView {
121142
}
122143

123144
// ["grayscaleTintLevel", "grayscaleTintAlpha", "lightenGrayscaleWithSourceOver", "colorTint", "colorTintAlpha", "colorBurnTintLevel", "colorBurnTintAlpha", "darkeningTintAlpha", "darkeningTintHue", "darkeningTintSaturation", "darkenWithSourceOver", "blurRadius", "saturationDeltaFactor", "scale", "zoom"]
145+
146+
private extension VisualEffectView {
147+
func makeBlurEffect(from style: BlurStyle) -> UIVisualEffect {
148+
switch style {
149+
case .system(let uiStyle):
150+
return UIBlurEffect(style: uiStyle)
151+
152+
case .custom:
153+
return UIBlurEffect(style: .light) // your existing custom pipeline
154+
}
155+
}
156+
157+
@available(iOS 26.0, *)
158+
private func makeGlassEffect(from style: GlassStyle) -> UIVisualEffect {
159+
return UIGlassEffect(style: style.value)
160+
}
161+
}

0 commit comments

Comments
 (0)