213

Could someone give a small example of applying the blur to an image? I've been trying to figure out the code for a while now :( still new at obj c!

The UIVisualEffectView provides a simple abstraction over complex visual effects. Depending on the desired effect, the results may affect content layered behind the view or content added to the view’s contentView.

Apply a UIVisualEffectView to an existing view to apply a blur or vibrancy effect to the exiting view. After you add the UIVisualEffectView to the view hierarchy, add any subviews to the contentView of the UIVisualEffectView. Do not add subviews directly to the UIVisualEffectView itself.

https://developer.apple.com/documentation/uikit/uivisualeffectview#//apple_ref/occ/instp/UIVisualEffectView/contentView

TheNeil
  • 3,321
  • 2
  • 27
  • 52
cNoob
  • 2,133
  • 3
  • 13
  • 4
  • 1
    Be careful to add views to `UIVisualEffectView` 's `contentView` https://github.com/onmyway133/blog/issues/124 – onmyway133 Dec 20 '17 at 10:42
  • Also if you are adding it to a subview and setting its frame don't forget to update the frame in viewDidLayoutSubviews to make sure rotation works. – Steve Moser Dec 16 '18 at 14:33

6 Answers6

422

Just put this blur view on the imageView. Here is an example in Objective-C:

UIVisualEffect *blurEffect;
blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];

UIVisualEffectView *visualEffectView;
visualEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];

visualEffectView.frame = imageView.bounds;
[imageView addSubview:visualEffectView];

and Swift:

var visualEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .Light))    

visualEffectView.frame = imageView.bounds

imageView.addSubview(visualEffectView)
Cesare
  • 9,139
  • 16
  • 78
  • 130
B.S.
  • 21,660
  • 14
  • 87
  • 109
  • 3
    thank you so much! I forgot about setting the frame :( There's nothing on google yet for visual, so this should be the first search term :) – cNoob Jun 06 '14 at 14:50
  • 1
    Better hope the API doesn’t change! That’s one of the reasons discussing not-yet-released Apple APIs can be tricky. For example, some of the UIKit Dynamics APIs change slightly between beta and release. Nothing major, but they would have broken any sample code written against the original APIs. – Zev Eisenberg Jun 06 '14 at 14:57
  • Would adding the vibrancy effect be this line? [UIVibrancyEffect effectForBlurEffect:blurEffect]; – cNoob Jun 06 '14 at 15:38
  • @cNoob Vibrancy is a totally different animal. You need to make a new view and add the vibrant content to the contentView of the UIEffectView and then add that as a subview of the blur view. – BlueSpud Jun 25 '14 at 04:15
  • 5
    Is there anyway to animate the blur in/out? – Ruben Martinez Jr. Aug 05 '14 at 14:15
  • Not tested, try to change it's alpha animated – B.S. Aug 05 '14 at 14:26
  • How can the effect style be changed on the fly without having to re-initialize visualEffectView? Say, visualEffectView.style = .Dark – ton Sep 22 '14 at 17:52
  • 3
    @B.S. You can animate the alpha of the visual effect view. Boom. – Maciej Trybiło Nov 18 '14 at 14:59
  • Can only support ios8? how about ios7 and below? – MeganZhou Dec 04 '14 at 03:10
  • 1
    is there a way to prevent this adding of the blureffect subview to cover other objects in the view controller? – Will Von Ullrich Jul 07 '15 at 20:36
  • 2
    UIBlurEffect is awesome, but note it doesn't work on older devices like iPad2's - I spent hours trying to figure out why it was only putting a translucent layer over my screen and not blurring - it was all because I was testing on an older device – Keith Jan 29 '16 at 14:30
  • @MaciejTrybiło you should not play with alpha while using `ÙIVisualEffectView` as Apple says "When using the UIVisualEffectView class, avoid alpha values that are less than 1" – Tapas Pal Sep 05 '16 at 07:45
136

Here is how to use UIVibrancyEffect and UIBlurEffect with UIVisualEffectView

Objective-C:

// Blur effect
UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
UIVisualEffectView *blurEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
[blurEffectView setFrame:self.view.bounds];
[self.view addSubview:blurEffectView];

// Vibrancy effect
UIVibrancyEffect *vibrancyEffect = [UIVibrancyEffect effectForBlurEffect:blurEffect];
UIVisualEffectView *vibrancyEffectView = [[UIVisualEffectView alloc] initWithEffect:vibrancyEffect];
[vibrancyEffectView setFrame:self.view.bounds];

// Label for vibrant text
UILabel *vibrantLabel = [[UILabel alloc] init];
[vibrantLabel setText:@"Vibrant"];
[vibrantLabel setFont:[UIFont systemFontOfSize:72.0f]];
[vibrantLabel sizeToFit];
[vibrantLabel setCenter: self.view.center];

// Add label to the vibrancy view
[[vibrancyEffectView contentView] addSubview:vibrantLabel];

// Add the vibrancy view to the blur view
[[blurEffectView contentView] addSubview:vibrancyEffectView];

Swift:

// Blur Effect
let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.dark)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView.frame = view.bounds
view.addSubview(blurEffectView)

// Vibrancy Effect
let vibrancyEffect = UIVibrancyEffect(blurEffect: blurEffect)
let vibrancyEffectView = UIVisualEffectView(effect: vibrancyEffect)
vibrancyEffectView.frame = view.bounds

// Label for vibrant text
let vibrantLabel = UILabel()
vibrantLabel.text = "Vibrant"
vibrantLabel.font = UIFont.systemFont(ofSize: 72.0)
vibrantLabel.sizeToFit()
vibrantLabel.center = view.center

// Add label to the vibrancy view
vibrancyEffectView.contentView.addSubview(vibrantLabel)

// Add the vibrancy view to the blur view
blurEffectView.contentView.addSubview(vibrancyEffectView)
pkamb
  • 33,281
  • 23
  • 160
  • 191
Matt Rundle
  • 1,609
  • 1
  • 9
  • 11
  • 1
    The workaround works even without subclassing, just define `extension UILabel { override func tintColorDidChange() { textColor = tintColor; super.tintColorDidChange() } }` – Palimondo Jun 16 '14 at 16:48
  • 1
    Im trying to add this to my view but every time I present the view, it gets blurred over and over until i get a white background... I am removing the view with removeFromSuperView after i dismiss it but i get the same result.... any ideas? – George Asda Nov 19 '14 at 17:39
  • @GeorgeAsda how about instead of calling `removeFromSuperView`, you make the `[self.visualEffectView setHidden:NO];` ? Allocate and adding onto the view is expensive operation than make hide or display. – Yoon Lee Feb 28 '17 at 01:58
47

You can also use the interface builder to create these effects easily for simple situations. Since the z-values of the views will depend on the order they are listed in the Document Outline, you can drag a UIVisualEffectView onto the document outline before the view you want to blur. This automatically creates a nested UIView, which is the contentView property of the given UIVisualEffectView. Nest things within this view that you want to appear on top of the blur.

XCode6 beta5

You can also easily take advantage of the vibrancy UIVisualEffect, which will automatically create another nested UIVisualEffectView in the document outline with vibrancy enabled by default. You can then add a label or text view to the nested UIView (again, the contentView property of the UIVisualEffectView), to achieve the same effect that the "> slide to unlock" UI element.

enter image description here

ohhh
  • 972
  • 9
  • 24
  • Can you confirm that what shows through is actually blurred? My image (what you called "BackgroundPhoto" in your hierarchy) is just dimmed under a Blur Style: Dark translucent view. (Release version of Xcode 6.01 and using the iOS Simulator) – tobinjim Sep 22 '14 at 18:33
  • What do you mean 'is just dimmed'? You don't think it's blurred then? – ohhh Sep 22 '14 at 18:36
  • Okay, I will take a look in a few hours. – ohhh Sep 22 '14 at 18:39
  • Thanks! You have a view hierarchy on your BackgroundPhoto that is collapsed in the screenshots... I just used a UIImageView and assigned a photo to it (a light colored dog against green background -- the sharp definition between the white legs and the green grass is just as sharp when covered by the visual effect view as when not). – tobinjim Sep 22 '14 at 18:42
  • I did all of my testing using Interface Builder, so no custom code at all. In the simulator, the iPad 2 produces no blur, but the iPad Air blurs as you would expect. – tobinjim Sep 22 '14 at 20:59
  • [I believe the effect is different on different devices](http://stackoverflow.com/questions/24129167/uivisualeffectview-renders-differently-on-different-devices). On the older devices it seems to dim and not blur (iPad 2 for example) – Paul de Lange Oct 03 '14 at 03:19
  • Hi there, @ohhh. I have the same configuration you have in the screenshots but when I try to change the color of the label I always get black color. Do you know why this is happening? – Daniel Oct 11 '14 at 15:10
  • 1
    I've seen that changing the type of the blur to Dark, the label gets white color... – Daniel Oct 11 '14 at 16:04
  • So I just confirmed that the blur will not look the same on older devices. Run on an older simulator and it will look like a dark/light opaque view. Newer devices blur correctly. – TheCodingArt Nov 02 '14 at 23:36
  • this is just so much better than having to do it in code. Thank you! – Ugo Jan 05 '21 at 12:05
8

I prefer creating Visual Effects via Storyboard - no code used for creating or maintaining UI Elements. It gives me full landscape support, too. I have made a little demo of using UIVisualEffects with Blur and also Vibrancy.

Demo on Github

Patrik Vaberer
  • 646
  • 6
  • 15
8

If anyone would like the answer in Swift :

var blurEffect = UIBlurEffect(style: UIBlurEffectStyle.Dark) // Change .Dark into .Light if you'd like.

var blurView = UIVisualEffectView(effect: blurEffect)

blurView.frame = theImage.bounds // 'theImage' is an image. I think you can apply this to the view too!

Update :

As of now, it's available under the IB so you don't have to code anything for it :)

Amit Kalra
  • 4,085
  • 6
  • 28
  • 44
2
-(void) addBlurEffectOverImageView:(UIImageView *) _imageView
{
    UIVisualEffect *blurEffect;
    blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];

    UIVisualEffectView *visualEffectView;
    visualEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];

    visualEffectView.frame = _imageView.bounds;
    [_imageView addSubview:visualEffectView];
}
Ramis
  • 13,985
  • 7
  • 81
  • 100