UITableView Blur Background Including Rotation Support

Let’s build a beautiful UITableView that has a UIVisualEffectView with a UIBlurEffect. Let’s also go further and avoid a common problem of the blur being offset from the underlying image and content during rotation.

There are actually several ways you can add a blur effect to a table. I’ll demonstrate an approach that I find the easiest to understand and implement, and one that doesn’t require any reference to frames and bounds in the code. Auto Layout and constraints to the rescue in this project.

This tutorial will demonstrate the blur effect for a table view by displaying famous quotes along with the author, so we’ll use dynamic prototype cells configured in the Storyboard to display the data nicely in each table row, with dynamically sized table rows. I won’t describe some of the basics in detail, such as adding constraints in the Storyboard, since that isn’t the focus for this tutorial.

With a Single View Application template, I’ll add a UIImageView under the View, and below that at the same level, I’ll add a UITableView. Based on the z order in Storyboards, this means that the UITableView is above the UIImageView. This is the beginning of setting up for the blur effect so that the image and blur are the background, and the text in the table view cells will be displayed in the color that we’ll specify.

I’ll add typical constraints with constants = 0 to make the UIImageView and UITableView align top/bottom/leading/trailing edges with the parent View.

Screen Shot 2016-04-21 at 12.58.34 PM

Next I add a nice image that will become the blurred background for the table. Then I’ll specify sunset.jpg as the Image for the UIImageView, and set the Mode to Aspect Fill so that the image fills the view but maintains its aspect ratio.

Screen Shot 2016-04-21 at 1.05.01 PM

In order to display famous quotes and the corresponding author, I’ll define the content of the table view cells in the Storyboard, using a dynamic prototype and custom table view cell. With the Table View selected in the Storyboard, and Content already specified as Dynamic Prototype, I’ll update the Prototype Cells to 1. This results in one prototype cell being displayed. You now see under Table View, a Table View Cell as well as its Content View, which is where I’ll design the content of the cell.

What I’ll do for this Content View is add two labels, one I’ll name Quote Label, and the other Author Label. Then I’ll put them in a vertical stack view, and leave the defaults for the stack view in place (Fill and Fill). Right now Auto Layout isn’t happy because it doesn’t know how to handle the stack view and its contents. We’ll fix that by adding constraints so the stack view fills the content view completely, but with constants of 7 so that the data is inset nicely from the edges. Finally, I also configure the following:

  • Spacing of 5 in the stack view.
  • Quote Label Lines = 0 so that it can handle multiple lines of quote text automatically.
  • Author Label Vertical Compression Resistance = 749 and Quote Label Vertical Compression Resistance = 751. This means if there was a need to compress one label beyond its intrinsic size, Auto Layout would choose the Author Label. In reality this won’t happen because later we’ll setup automatic table cell sizing so that the cells expand or shrink based on the data in the cell.
  • Left alignment of the Quote Label and right alignment of the Author Label.
  • Identifier value for Table View Cell is set to quoteCell. This is how we’ll access the cell in code.

One last set of configuration in the Storyboard before we write code. All the views need to have a clear background, including the labels, and the text color of the labels we’ll set to white. With these changes, our blur effect that will be behind the table will be fully visible, with data on top of it. This means we set Background to Clear Color for Table View, Table View Cell, Content View, Quote Label, and Author Label. Stack views are never drawn so background color is ignored for it. You can see the end result of all the changes in the completed project.

Now we can start to write some code. We need to access the UIImageView in the controller, so we create an IBOutlet for it. That will enable us to access the image view so that we can add the blur effect to it. Since we have a UIViewController, we also need an IBOutlet for the UITableView, and we need to declare that the controller conforms to UITableViewDataSource and UITableViewDelegate protocols.

I’m going to add a few other lines of code, including a Struct for quotes and a custom color for selection background. There are comments describing details. We’re just getting setup to have everything in place so we can run it soon. The entire ViewController so far is now the following.

There are errors because the required methods for the protocols are not yet defined. One more piece to add first though, which is a UITableViewCell subclass for the dynamic prototype we defined, so that we can access the labels from this cell. Once the QuoteTableViewCell class is created, as a child of UITableViewCell, in the Storyboard the quoteCell needs to have its Custom Class > Class value set to QuoteTableViewCell. Then outlets can be created and our new class would look as follows.

Now lets add the required methods for the two protocols. I’ve added comments to make this as self explanatory as possible so we can finally get right to the blur code.

We can now run it, just to verify what it looks like prior to adding the blur effect. This is what it looks like with the second row selected in the Chevy Orange background selection color that was defined in the controller. Note that separators are known to not work very well on the simulator, and indeed you can’t see them in this screenshot.

Simulator Screen Shot Apr 21, 2016, 3.33.01 PM

I actually find it quite cool to look at the screen just like it is, but let’s get the blur effect implemented. This is the magic function that we need.

I’ve added comments again to make it as clear as possible from reading the code. If we had added the imageView as the table background in code, and then added the blurView as a subview of the imageView, we would see that when rotating the device, the blur is not rotating smoothly with the rest of the view, so the solution is deficient in that case.

This technique above overcomes that by first adding the imageView into the Storyboard behind the tableView as I mentioned earlier. We gave it constraints so that it is now constrained to the view as it rotates. In the code above, there are two choices for how to add the blurView so it is ahead of the imageView. Either results in the blurView on top of the imageView, which means the image is blurred. Constraints are defined to keep the bounds of the blur the same as the view (and the imageView), and for those to work, we needed to set translatesAutoresizingMaskIntoConstraints = false for the blurView.

We need to call this method from the viewDidLoad, so I’ve added this line at the end of the method.

Here is the result with the Dark style UIBlurEffect now applied.

Simulator Screen Shot Apr 21, 2016, 3.55.03 PM

I changed the scale of the simulator for this screenshot, and you can see it is now showing some lines. I’ve also selected the third quote in this case. I like the effect of the selection color with the blur and image.

There is one more tweak we can apply, which is to give a vibrancy effect to the lines to make them appear somewhat transparent and colored like the blur as well. This one line does that, added to the end of the addBlurEffect method.

Here is another screenshot with the separatorEffect added and the last quote selected.

Simulator Screen Shot Apr 21, 2016, 4.06.54 PM
If you want to see it with a lighter blur effect, simply change .Dark to .Light in the addBlurEffect method and run it.

Before I wrap up this post, I wanted to add a couple of thoughts regarding other methods of using the UIVisualEffectView with a UITableView. Trying to add all components directly to the Storyboard was not as intuitive in my opinion, and I ran into a few issues. Another approach I’ve experimented with is having two views in the Storyboard, one for the table view, and another view that has the image and visual effect. This was more work and again not as intuitive. I already talked briefly about adding both the image view and blur view in code.

After trying the various approaches, the way I’ve shown was in my opinion easier and intuitive, and did not present issues as the other techniques did. One advantage of this method is that it allows the entire view to be created and run successfully just as you would normally, and then only one method is needed to layer in the blur effect and handle blur rotation correctly. Being able to add some constraints and let Auto Layout take over from there is a bonus.

Here is a screen capture of the rotation. If you’ve seen a rotation without constraints setup properly, you should notice a difference with the blur being handled correctly.

Thank you for humoring me as I took the time to setup a project that displayed more than single lines of demo text in the table view 🙂

The completed project is in GitHub, and as always, feedback and comments are welcome.

Leave a Comment:

Add Your Reply