Blur Effect inside SwiftUI
Creating SwiftUI Blur view
SwiftUI does not have a built in visual effects view. However it’s easy to mix UIKit with SwiftUI using UIViewRepresentable. Here’s the code to create a SwiftUI version of UIVisualEffectView to be used as a background view. NOTE: This article does not cover vibrancy.
Line 3: BlurEffect.Style Property defaulting to .systemMaterial. This value can be changed using the struct’s automatic initializer. For example Blur(style: .systemThinMaterial)
var style: UIBlurEffect.Style = .systemMaterial
Lines 4–6: implementation of makeUIView, creates a UIVisualEffectView using the correct blur effect.
func makeUIView(context: Context) -> UIVisualEffectView {
return UIVisualEffectView(effect: UIBlurEffect(style: style))
}
Line 7–9: implementation of updateUIView, updates the effect when user changes the blur style.
func updateUIView(_ uiView: UIVisualEffectView, context: Context){
uiView.effect = UIBlurEffect(style: style)
}
Using the Blur View
Now the fun part! We are ready to use the Blur view as a background view inside SwiftUI.
Here’s the simpliest approach. Add Blur() to any view’s background. This defaults to .systemMaterial style. This will automatically adjusts based on dark mode.
Text("World's Greatest Flag")
.font(.largeTitle)
.padding()
.background(Blur()) // Blur defaults to .systemMaterial
.cornerRadius(15.0)
You can adjust the Blur style to any available style: The list of styles are here: https://developer.apple.com/documentation/uikit/uiblureffect/style. It’s highly suggested to use the following adaptable styles which automatically adjust based on dark mode (on/off).
- .systemUltraThinMaterial
- .systemThinMaterial
- .systemMaterial
- .systemThickMaterial
- .systemChromeMaterial.
// example using .systemUltraThinMaterialText("World's Greatest Flag")
.font(.largeTitle)
.padding()
.background(Blur(style: .systemUltraThinMaterial))
.cornerRadius(15.0)
The following code gist shows a picker to choose between 5 different styles.
Lines 29–33: styleIndex is state variable that changes when user selects from picker.
Text("World's Greatest Flag")
.font(.largeTitle)
.padding()
.background(Blur(style: self.styles[self.styleIndex].style))
.cornerRadius(15.0)
Works in dark mode
Since I’m using only adaptive styles. The blur effect automatically adjusts to dark mode.