How to set the BlurRadius of UIBlurEffectStyle.Light
How to set the BlurRadius of UIBlurEffectStyle.Light
I was wondering how to set the radius/blur factor of iOS new UIBlurEffectStyle.Light? I could not find anything in the documentation. But I want it to look similar to the classic "UIImage+ImageEffects.h" blur effect.
Thanks,
required init(coder aDecoder: NSCoder)
super.init(coder: aDecoder)
let blur:UIBlurEffect = UIBlurEffect(style: UIBlurEffectStyle.Light)
let effectView:UIVisualEffectView = UIVisualEffectView (effect: blur)
effectView.frame = frame
addSubview(effectView)
9 Answers
9
You can change the alpha of the UIVisualEffectView that you add your blur effect to.
let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.Light)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView.alpha = 0.5
blurEffectView.frame = self.view.bounds
self.view.addSubview(blurEffectView)
This is not a true solution, as it doesn't actually change the radius of the blur, but I have found that it gets the job done with very little work.
@Kwalker108. nice workaround. Thanks!
– GoGreen
Dec 23 '15 at 4:39
When using the UIVisualEffectView class, avoid alpha values that are less than 1. Creating views that are partially transparent causes the system to combine the view and all the associated subviews during an offscreen render pass. UIVisualEffectView objects need to be combined as part of the content they are layered on top of in order to look correct. Setting the alpha to less than 1 on the visual effect view or any of its superviews causes many effects to look incorrect or not show up at all. developer.apple.com/library/tvos/documentation/UIKit/Reference/…
– sabalaba
Jan 9 '16 at 20:56
Although it is a hack and probably it won't be accepted in the app store, it is still possible. You have to subclass the UIBlurEffect
like this:
UIBlurEffect
#import <objc/runtime.h>
@interface UIBlurEffect (Protected)
@property (nonatomic, readonly) id effectSettings;
@end
@interface MyBlurEffect : UIBlurEffect
@end
@implementation MyBlurEffect
+ (instancetype)effectWithStyle:(UIBlurEffectStyle)style
id result = [super effectWithStyle:style];
object_setClass(result, self);
return result;
- (id)effectSettings
id settings = [super effectSettings];
[settings setValue:@50 forKey:@"blurRadius"];
return settings;
- (id)copyWithZone:(NSZone*)zone
id result = [super copyWithZone:zone];
object_setClass(result, [self class]);
return result;
@end
Here blur radius is set to 50. You can change 50 to any value you need.
Then just use MyBlurEffect
class instead of UIBlurEffect
when creating your effect for UIVisualEffectView
.
MyBlurEffect
UIBlurEffect
UIVisualEffectView
I swear they announced at the platforms state of the union that you can modify the blurRadius! But its not in any docs that I could find!
– Santa Claus
Jul 5 '15 at 19:16
This sholution doesn't work. After changing blurRadius error occures:
malloc: *** error for object 0x7fbf9969b690: incorrect checksum for freed object - object was probably modified after being freed. *** set a breakpoint in malloc_error_break to debug
– Sound Blaster
Jul 21 '15 at 12:10
malloc: *** error for object 0x7fbf9969b690: incorrect checksum for freed object - object was probably modified after being freed. *** set a breakpoint in malloc_error_break to debug
Works perfectly if to do it exactly how it is written in the answer. If you modify blur radius after adding the BlurEffect onto the Effect View - you are doing wrong. The BlurEffect is copied during adding, and the instance you are modifying is not used by an EffectView.
– DisableR
Jul 21 '15 at 12:18
Is only one take this answer and accepted in the app store?
– mayqiyue
Apr 11 '16 at 10:17
this works, but it doesn't show gradual changes in blur radius going - let's say - from radius 1 to 5 or 10... (at least in the simulator)
– eddyce
Sep 10 '16 at 14:56
Recently developed Bluuur
library to dynamically change blur radius of UIVisualEffectsView
without usage any of private APIs: https://github.com/ML-Works/Bluuur
Bluuur
UIVisualEffectsView
It uses paused animation of setting effect
to achieve changing radius of blur. Solution based on this gist: https://gist.github.com/n00neimp0rtant/27829d87118d984232a4
effect
And the main idea is:
// Freeze animation
blurView.layer.speed = 0;
blurView.effect = nil;
[UIView animateWithDuration:1.0 animations:^
blurView.effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
];
// Set animation progress from 0 to 1
blurView.layer.timeOffset = 0.5;
UPDATE:
Apple introduced UIViewPropertyAnimator class in iOS 10. Thats what we need exactly to animate .effect
property of UIVisualEffectsView
. Hope community will be able to back-port this functionality to previous iOS version.
.effect
UIVisualEffectsView
This should really be the accepted answer. Currently accepted one goes directly against Apple's guidelines.
– tomas789
Mar 28 '17 at 12:54
Since December 2016 and the commit github.com/ML-Works/Bluuur/commit/… the Bluuur project does use private API to change the blurRadius! See this issue: github.com/ML-Works/Bluuur/issues/17
– void256
May 18 '17 at 13:57
@void256 thanks! This approach works more stable especially with animations.
– k06a
May 18 '17 at 14:03
Changing alpha is not a perfect solution. It does not affect blur intensity. You can setup an animation from nil
to target blur effect and manually set time offset to get desired blur intensity. Unfortunately iOS will reset the animation offset when app returns from background.
nil
Thankfully there is a simple solution that works on iOS >= 10. You can use UIViewPropertyAnimator
. I didn't notice any issues with using it. I keeps custom blur intensity when app returns from background. Here is how you can implement it:
UIViewPropertyAnimator
class CustomIntensityVisualEffectView: UIVisualEffectView
/// Create visual effect view with given effect and its intensity
///
/// - Parameters:
/// - effect: visual effect, eg UIBlurEffect(style: .dark)
/// - intensity: custom intensity from 0.0 (no effect) to 1.0 (full effect) using linear scale
init(effect: UIVisualEffect, intensity: CGFloat)
super.init(effect: nil)
animator = UIViewPropertyAnimator(duration: 1, curve: .linear) [unowned self] in self.effect = effect
animator.fractionComplete = intensity
required init?(coder aDecoder: NSCoder)
fatalError()
// MARK: Private
private var animator: UIViewPropertyAnimator!
I also created a gist: https://gist.github.com/darrarski/29a2a4515508e385c90b3ffe6f975df7
I'm afraid there's no such api currently. According to Apple's way of doing things, new functionality was always brought with restricts, and capabilities will bring out gradually. Maybe that will be possible on iOS 9 or maybe 10...
True. I mean we didn't even have a UIVisualEffectView before, so things are slowly improving.
– devios1
May 19 '15 at 23:25
Hello from 2016. iOS 9.2 is out and still no blurRadius.
– mojuba
Feb 6 '16 at 19:06
Maybe next year...
– Louis Zhu
Feb 29 '16 at 6:19
Does iOS 10 have this? Haven't seen this in any docs…
– Luke Taylor
Jul 14 '16 at 18:49
iOS10? Still no ¯_(ツ)_/¯
– everm1nd
Sep 20 '16 at 20:20
Currently I didn't find any solution.
By the way you can add a little hack in order to let blur mask less "blurry", in this way:
let blurView = .. // here create blur view as usually
if let blurSubviews = self.blurView?.subviews
for subview in blurSubviews
if let filterView = NSClassFromString("_UIVisualEffectFilterView")
if subview.isKindOfClass(filterView)
subview.hidden = true
This is totally doable. Use CIFilter
in CoreImage
module to customize blur radius. In fact, you can even achieve a blur effect with continuous varying (aka gradient) blur radius (https://stackoverflow.com/a/51603339/3808183)
CIFilter
CoreImage
import CoreImage
let ciContext = CIContext(options: nil)
guard let inputImage = CIImage(image: yourUIImage),
let mask = CIFilter(name: "CIGaussianBlur") else return
mask.setValue(inputImage, forKey: kCIInputImageKey)
mask.setValue(10, forKey: kCIInputRadiusKey) // Set your blur radius here
guard let output = mask.outputImage,
let cgImage = ciContext.createCGImage(output, from: inputImage.extent) else return
outUIImage = UIImage(cgImage: cgImage)
This works for me.
I put UIVisualEffectView
in an UIView
before add to my view.
UIVisualEffectView
UIView
I make this function to use easier. You can use this function to make blur any area in your view.
func addBlurArea(area: CGRect)
let effect = UIBlurEffect(style: UIBlurEffectStyle.Dark)
let blurView = UIVisualEffectView(effect: effect)
blurView.frame = CGRect(x: 0, y: 0, width: area.width, height: area.height)
let container = UIView(frame: area)
container.alpha = 0.8
container.addSubview(blurView)
self.view.insertSubview(container, atIndex: 1)
For example, you can make blur all of your view by calling:
addBlurArea(self.view.frame)
You can change Dark
to your desired blur style and 0.8
to your desired alpha value
Dark
0.8
this doesn't answer the question at all. OP asked how to change blur radius, not how to add UIVisualEffectView to your app
– Lope
Jul 30 '16 at 11:50
Yes, it is. The blur radius value is directly related to alpha value I mentioned in the answer.
– Demilitarized Zone
Aug 1 '16 at 3:28
If you want to accomplish the same behaviour as iOS spotlight search you just need to change the alpha value of the UIVisualEffectView (tested on iOS9 simulator)
Changing the alpha doesn't give you the same result at all.. you have to change the blur radius to do that.
– Jacopo Penzo
Oct 20 '16 at 4:31
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
While not addressing the core problem, this is certainly a very nice workaround and more likely to be accepted into the store! Nice one.
– ColinMasters
Oct 10 '15 at 14:54