iOS 7 style Blur view

IosObjective CCore Graphics

Ios Problem Overview


Does anybody know of any controls that will replicate the iOS7 style blur views.

I'm assumming there can be some kind of UIView subclass that will replicate the behavior.

I'm talking about these type views which blur the background extremely thickly so that they have pull effects from the background view.

enter image description here

Ios Solutions


Solution 1 - Ios

You might be able to modify something like Bin Zhang's RWBlurPopover to do this. That component uses my GPUImage to apply a Gaussian blur to components underneath it, but you could just as easily use a CIGaussianBlur for the same. GPUImage might be a hair faster though.

That component relies on you being able to capture the view behind the one you're presenting, though, and may have trouble with views that animate behind this content. The need to take a trip through Core Graphics to rasterize the background view will slow things down, so we probably don't have sufficiently direct access to be able to do this in a performant manner for overlays on animating views.

As an update to the above, I recently reworked the blurs in GPUImage to support variable radii, allowing for the complete replication of the blur size in iOS 7's control center view. From that, I created the GPUImageiOS7BlurFilter class that encapsulates the proper blur size and color correction that Apple appears to be using here. This is how GPUImage's blur (on the right) compares to the built-in blur (on the left):

Apple's blur GPUImage's blur

I use a 4X downsampling / upsampling to reduce the number of pixels the Gaussian blur has to operate over, so an iPhone 4S can blur the entire screen in roughly 30 ms using this operation.

You still have the challenge of how to pull content into this blur from views behind this one in a performant manner.

Solution 2 - Ios

I am using FXBlurView which works great on iOS5+

https://github.com/nicklockwood/FXBlurView

CocoaPods:

-> FXBlurView (1.3.1)
   UIView subclass that replicates the iOS 7 realtime background blur effect, but works on iOS 5 and above.
   pod 'FXBlurView', '~> 1.3.1'
   - Homepage: http://github.com/nicklockwood/FXBlurView
   - Source:   https://github.com/nicklockwood/FXBlurView.git
   - Versions: 1.3.1, 1.3, 1.2, 1.1, 1.0 [master repo]

I added it by using:

FXBlurView *blurView = [[FXBlurView alloc] initWithFrame:CGRectMake(50, 50, 150, 150)];
[self.blurView setDynamic:YES];
[self.view addSubview:self.blurView];

Solution 3 - Ios

WARNING: someone in the comments stated that Apple rejects apps using this technique. That did NOT happen to me, but just for your consideration.

This may surprise you, but you can use a UIToolbar, which already includes that standard effect (only iOS 7+). In you view controller's viewDidLoad:

self.view.opaque = NO;
self.view.backgroundColor = [UIColor clearColor]; // Be sure in fact that EVERY background in your view's hierarchy is totally or at least partially transparent for a kind effect!

UIToolbar *fakeToolbar = [[UIToolbar alloc] initWithFrame:self.view.bounds];
fakeToolbar.autoresizingMask = self.view.autoresizingMask;
// fakeToolbar.barTintColor = [UIColor white]; // Customize base color to a non-standard one if you wish
[self.view insertSubview:fakeToolbar atIndex:0]; // Place it below everything

Solution 4 - Ios

Since iOS8 you can use UIBlurEffect.

There are a good exemples on iOS8Sampler with UIBlurEffect and UIVibrancyEffect.

Solution 5 - Ios

The best new Way to get a blured Overlay is to use the new iOS 8 Feature UIVisualEffectView.

UIBlurEffect *effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];

UIVisualEffectView *bluredView = [[UIVisualEffectView alloc] initWithEffect:effect];

bluredView.frame = self.view.bounds;

[self.view addSubview:bluredView];

The UIBlurEffect supports three kinds of Style. Dark, Light and ExtraLight.

Solution 6 - Ios

You can create a class with a UIToolBar that is a subclass of UIView and instantiate it in a separate view controller. This approach demonstrates a translucent UIToolBar (subclassed by UIView) that provides live feedback (in this case for an AVCaptureSession).

YourUIView.h

#import <UIKit/UIKit.h>

@interface YourUIView : UIView
@property (nonatomic, strong) UIColor *blurTintColor;
@property (nonatomic, strong) UIToolbar *toolbar;
@end

YourUIView.m

#import "YourUIView.h"

@implementation YourUIView

- (instancetype)init
{
    self = [super init];
    if (self) {
        [self setup];
    }
    return self;
}

- (void)setup {
    // If we don't clip to bounds the toolbar draws a thin shadow on top
    [self setClipsToBounds:YES];
    
    if (![self toolbar]) {
        [self setToolbar:[[UIToolbar alloc] initWithFrame:[self bounds]]];
        [self.toolbar setTranslatesAutoresizingMaskIntoConstraints:NO];
        [self insertSubview:[self toolbar] atIndex:0];
        
        [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_toolbar]|"
                                                                     options:0
                                                                     metrics:0
                                                                       views:NSDictionaryOfVariableBindings(_toolbar)]];
        [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_toolbar]|"
                                                                     options:0
                                                                     metrics:0
                                                                       views:NSDictionaryOfVariableBindings(_toolbar)]];
    }
}

- (void) setBlurTintColor:(UIColor *)blurTintColor {
    [self.toolbar setBarTintColor:blurTintColor];
}

@end

Once the above UIView has been customized, go ahead and create a class that is a subclass of a ViewController. Below I have created a class that is using an AVCapture session. You must use AVCaptureSession in order to override apple's built in camera configuration. Thus you can overlay the tranclucent UIToolBar from the YourUIView class.

YourViewController.h

#import <UIKit/UIKit.h>

@interface YourViewController : UIViewController
@property (strong, nonatomic) UIView *frameForCapture;
@end

YourViewController.m

#import "YourViewController.h"
#import <AVFoundation/AVFoundation.h>
#import "TestView.h"

@interface YourViewController ()
@property (strong, nonatomic) UIButton *displayToolBar;

@end

@implementation YourViewController


AVCaptureStillImageOutput *stillImageOutput;
AVCaptureSession *session;

- (void) viewWillAppear:(BOOL)animated
{
    session = [[AVCaptureSession alloc] init];
    [session setSessionPreset:AVCaptureSessionPresetPhoto];
    
    AVCaptureDevice *inputDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    NSError *error;
    AVCaptureDeviceInput *deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:inputDevice error:&error];
    
    if ([session canAddInput:deviceInput]) {
        [session addInput:deviceInput];
    }
    
    AVCaptureVideoPreviewLayer *previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
    [previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
    CALayer *rootLayer = [[self view] layer];
    [rootLayer setMasksToBounds:YES];
    CGRect frame = [[UIScreen mainScreen] bounds];
    
    self.frameForCapture.frame = frame;
    
    [previewLayer setFrame:frame];
    
    [rootLayer insertSublayer:previewLayer atIndex:0];
    
    stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
    NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys:AVVideoCodecJPEG, AVVideoCodecKey, nil];
    [stillImageOutput setOutputSettings:outputSettings];
    
    [session addOutput:stillImageOutput];
    
    [session startRunning];
    
    [self.navigationController setNavigationBarHidden:YES animated:animated];
    [super viewWillAppear:animated];
}


- (void)viewDidLoad
{
    [super viewDidLoad];
    
    /* Open button */
    
    UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 350, self.view.bounds.size.width, 50)];
    [button addTarget:self action:@selector(showYourUIView:) forControlEvents:UIControlEventTouchUpInside];
    [button setTitle:@"Open" forState:UIControlStateNormal];
    [button setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
    button.backgroundColor = [UIColor greenColor];
    [self.view addSubview:button];
    
    UIButton *anotherButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 50, self.view.bounds.size.width, 50)];
    [anotherButton addTarget:self action:@selector(showYourUIView:) forControlEvents:UIControlEventTouchUpInside];
    [anotherButton setTitle:@"Open" forState:UIControlStateNormal];
    [anotherButton setTitleColor:[UIColor greenColor] forState:UIControlStateNormal];
    anotherButton.backgroundColor = [UIColor redColor];
    [self.view addSubview:anotherButton];

}

- (void) showYourUIView:(id) sender
{
    TestView *blurView = [TestView new];
    [blurView setFrame:self.view.bounds];
    [self.view addSubview:blurView];
}


@end

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionendyView Question on Stackoverflow
Solution 1 - IosBrad LarsonView Answer on Stackoverflow
Solution 2 - IosPaul PeelenView Answer on Stackoverflow
Solution 3 - IoscprcrackView Answer on Stackoverflow
Solution 4 - IosVivienCormierView Answer on Stackoverflow
Solution 5 - IosJeanette MüllerView Answer on Stackoverflow
Solution 6 - Ios74U n3U7r1noView Answer on Stackoverflow