UIVisualEffectView Tutorial: Getting Started
In this UIVisualEffectView tutorial, you’ll learn how blurs work on a technical level and how to add native blur and vibrancy effects to your own apps. By Ron Kliffer.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
UIVisualEffectView Tutorial: Getting Started
15 mins
Blur Effects Using UIVisualEffectView
UIKit provides an entire suite of visual effects goodies. UIBlurEffect
, a subclass of UIVisualEffect
, is particularly relevant, as it provides the nice blurs you see in navigation bars, Notification Center and Control Center — and you can use it in your apps as well.
Adding a UIBlurEffect
In this project, you’ll use blur to make OptionsViewController
stand out on top of the story.
Open OptionsViewController.swift and add the following code to the end of viewDidLoad()
:
// 1
view.backgroundColor = .clear
// 2
let blurEffect = UIBlurEffect(style: .light)
// 3
let blurView = UIVisualEffectView(effect: blurEffect)
// 4
blurView.translatesAutoresizingMaskIntoConstraints = false
view.insertSubview(blurView, at: 0)
Here’s what you’re doing in the code above:
- In order for
UIVisualEffectView
to actually blur the content, its superview must be transparent. To make it transparent, change the background color ofview
toclear
. - Create a
UIBlurEffect
with aUIBlurEffect.Style.light
style. This defines the blur style. There are many different styles; check the documentation to see the full list. - Create a
UIVisualEffectView
with the blur you just created. This class is a subclass ofUIView
. Its sole purpose is to define and display complex visual effects. - Disable translating the auto-resizing masks into constraints on
blurView
— you’ll manually add constraints in a moment — and add it at the bottom of the view stack. If you addedblurView
on top of the view, it would blur all the controls underneath it instead!
Now you need to ensure blurView
is laid out properly with the rest of the view.
Add the following code to the end of viewDidLoad
:
NSLayoutConstraint.activate([
blurView.topAnchor.constraint(equalTo: view.topAnchor),
blurView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
blurView.heightAnchor.constraint(equalTo: view.heightAnchor),
blurView.widthAnchor.constraint(equalTo: view.widthAnchor)
])
These constraints keep the frame of blurView
consistent with that of OptionsViewController
.
Build and run. Select a fairy tale, tap the settings button and then scroll the text. You’ll see the blur update in real time.
Toggle the Reading Mode and notice how the blurred background changes:
You now have a dynamic blur effect in your app that was not only easy to implement, but looks great too.
Adding Vibrancy to Your Blur
Blur effects are great‚ but as usual, Apple has taken it to the next level with UIVibrancyEffect
. Vibrancy, when used in combination with UIVisualEffectView
, adjusts the colors of the content to make it feel more vivid.
The following image shows how vibrancy makes your labels and icons pop off the screen, while at the same time blending with the background itself:
The left side of the image above shows a normal label and button, while the right side shows a label and button with vibrancy applied.
UIVibrancyEffect
to the contentView
of a UIVisualEffectView
that has been set up and configured with a UIBlurEffect
object. Otherwise, there won’t be any blurs to apply a vibrancy effect to!Open OptionsViewController.swift and add the following code to the end of viewDidLoad()
:
// 1
let vibrancyEffect = UIVibrancyEffect(blurEffect: blurEffect)
// 2
let vibrancyView = UIVisualEffectView(effect: vibrancyEffect)
vibrancyView.translatesAutoresizingMaskIntoConstraints = false
// 3
vibrancyView.contentView.addSubview(optionsView)
// 4
blurView.contentView.addSubview(vibrancyView)
In the code above, you:
- Create a
UIVibrancyEffect
that uses theblurEffect
you set up earlier.UIVibrancyEffect
is another subclass ofUIVisualEffect
. - Create a
UIVisualEffectView
to contain the vibrancy effect. This process is exactly the same as creating a blur. Since you’re using Auto Layout, you make sure to disable auto-resizing translations here. - Add
optionsView
as a subview of your vibrancy view’scontentView
. This ensures the vibrancy effect is applied to the view that contains all the controls. - Add the vibrancy view to the blur view’s
contentView
to complete the effect.
Next you need to set up the Auto Layout constraints for the vibrancy view so that it has the same dimensions as the blur view. Then be sure to center the options view in the vibrancy view.
Add the following constraints at the end of viewDidLoad()
:
NSLayoutConstraint.activate([
vibrancyView
.heightAnchor
.constraint(equalTo: blurView.contentView.heightAnchor),
vibrancyView
.widthAnchor
.constraint(equalTo: blurView.contentView.widthAnchor),
vibrancyView
.centerXAnchor
.constraint(equalTo: blurView.contentView.centerXAnchor),
vibrancyView
.centerYAnchor
.constraint(equalTo: blurView.contentView.centerYAnchor)
])
NSLayoutConstraint.activate([
optionsView
.centerXAnchor
.constraint(equalTo: vibrancyView.contentView.centerXAnchor),
optionsView
.centerYAnchor
.constraint(equalTo: vibrancyView.contentView.centerYAnchor)
])
Build and run. Navigate to the options view to see your new vibrancy effect in action:
Unless you have high-contrast vision, the vibrancy effect makes it difficult to read the labels and controls. What’s going on?
Ah — the content behind the blur view is light and you’re applying a UIBlurEffect.Style.light
effect. That’s counterproductive, to be sure.
Change the line near the top of viewDidLoad()
that initializes blurEffect
:
let blurEffect = UIBlurEffect(style: .dark)
The change from a light
style to a dark
style adds more contrast between the background and text.
Build and run. You’re now experiencing some true vibrancy:
Accessibility
However, when it comes to blurs, there’s one last thing you need to consider: What if the user has blurs disabled?
In the simulator or on your device, open the Settings app and go to Accessibility ▸ Display & Text Size, and enable Reduce Transparency. Go back to the app and open the options view once again.
Well, that’s a bit dark. Going back to what you started out with is a better alternative.
Fortunately, you can check if this accessibility setting is enabled using UIAccessibility.isReduceTransparencyEnabled
. If you know that this setting is on, you can change the way your app looks and behaves.
Add the following right before you set the view’s background color in viewDidLoad()
:
guard !UIAccessibility.isReduceTransparencyEnabled else {
return
}
This code checks to see if Reduce Transparency is on. If it is, ignore all the code you just wrote and go back to the original layout without any blurring.
Build and run, and you’ll see that the options menu’s background is no longer blurred:
Where to Go From Here?
Download the completed version of the project by clicking the Download Materials button at the top or bottom of this tutorial.
You’ve seen how to blur images, as well as how to create real-time blur effects using UIVisualEffectView. You can just as easily add advanced blur effects to your own app! There are many more effects and options you could dive in to, and the best place to continue your exploration would be in Apple’s official UIVisualEffectView documentation.
UIVisualEffectView
s update in real time, so you can achieve all sorts of weird and wonderful things with these effects. While it’s tempting to go ahead and blur all the things, remember the tips from earlier in the tutorial regarding using these effects sparingly and only where appropriate. As is often the case, with blur and vibrancy, less is definitely more.
If you have any questions or comments about this UIVisualEffectView tutorial or visual effects in general, please join the forum discussion below!