iOS 7 Translucent Modal View Controller

35,742

Solution 1

With the release of iOS 8.0, there is no need for getting an image and blurring it anymore. As Andrew Plummer pointed out, you can use UIVisualEffectView with UIBlurEffect.

UIViewController * contributeViewController = [[UIViewController alloc] init];
UIBlurEffect * blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
UIVisualEffectView *beView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
beView.frame = self.view.bounds;

contributeViewController.view.frame = self.view.bounds;
contributeViewController.view.backgroundColor = [UIColor clearColor];
[contributeViewController.view insertSubview:beView atIndex:0];
contributeViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext;

[self presentViewController:contributeViewController animated:YES completion:nil];

Solution that works before iOS 8

I would like to extend on rckoenes' answer:

As emphasised, you can create this effect by:

  1. Convert the underlying UIView to an UIImage
  2. Blur the UIImage
  3. Set the UIImage as background of your view.

enter image description here


Sounds like a lot of work, but is actually done pretty straight-forward:

1. Create a category of UIView and add the following method:

-(UIImage *)convertViewToImage
{
    UIGraphicsBeginImageContext(self.bounds.size);
    [self drawViewHierarchyInRect:self.bounds afterScreenUpdates:YES];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return image;
}

2. Make an image of the current view and blur it by using Apple's Image Effect category (download)

UIImage* imageOfUnderlyingView = [self.view convertViewToImage];
imageOfUnderlyingView = [imageOfUnderlyingView applyBlurWithRadius:20
                             tintColor:[UIColor colorWithWhite:1.0 alpha:0.2]
                 saturationDeltaFactor:1.3
                             maskImage:nil];

3. Set it as background of your overlay.

-(void)viewDidLoad
{
   self.view.backgroundColor = [UIColor clearColor];
   UIImageView* backView = [[UIImageView alloc] initWithFrame:self.view.frame];
   backView.image = imageOfUnderlyingView;
   backView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.6];
   [self.view addSubview:backView];
}

Solution 2

Just reimplemented Sebastian Hojas' solution in Swift:

1. Create a UIView extension and add the following method:

extension UIView {
    func convertViewToImage() -> UIImage{
        UIGraphicsBeginImageContext(self.bounds.size);
        self.drawViewHierarchyInRect(self.bounds, afterScreenUpdates: true)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext();

        return image;
    }
}

2. Make an image of the current view and blur it by using Apple's Image Effect (I found a reimplementation of this in Swift here: SwiftUIImageEffects

var imageOfUnderlyingView = self.view.convertViewToImage()
imageOfUnderlyingView = imageOfUnderlyingView.applyBlurWithRadius(2, tintColor: UIColor(white: 0.0, alpha: 0.5), saturationDeltaFactor: 1.0, maskImage: nil)!

3. Set it as background of your overlay.

let backView = UIImageView(frame: self.view.frame)
backView.image = imageOfUnderlyingView
backView.backgroundColor = UIColor.blackColor().colorWithAlphaComponent(0.5)
view.addSubview(backView)

Solution 3

I think this is the easiest solution for a modal view controller that overlays everything with a nice blur (iOS8)

    UIViewController * contributeViewController = [[UIViewController alloc] init];

    UIBlurEffect * blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
    UIVisualEffectView *beView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
    beView.frame = self.view.bounds;

    contributeViewController.view.frame = self.view.bounds;
    contributeViewController.view.backgroundColor = [UIColor clearColor];
    [contributeViewController.view insertSubview:beView atIndex:0];
    contributeViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext;

    [self presentViewController:contributeViewController animated:YES completion:nil];

Solution 4

There is no API available in the iOS 7 SDK which will allow you to "frost" the underlaying view controller.

What I have done is render the underlaying view to an image, which I then frosted and set that as background the the view that is being presented.

Apple provides a good example for this: https://developer.apple.com/downloads/index.action?name=WWDC%202013

The project you want is called, iOS_RunningWithASnap

Solution 5

A little simplier way to achieve this (based on Andrew Plummer's answer) with Interface Builder (also it removes side effect that appears in Andrews answer):

  • In IB add Visual Effect View to your View Controller under your other views;
  • Make top, bottom, left, right constraints from Visual Effect View to top (parent) View, set all of them to 0;
  • Set Blur Style;
  • Add the code where you present your new fancy View Controller:

UIViewController *fancyViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"yourStoryboardIDFOrViewController"];

fancyViewController.view.backgroundColor = [UIColor clearColor];
fancyViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext;

[self presentViewController:fancyViewController
                   animated:YES
                 completion:nil];

Actually, the second and third lines are VERY important - otherwise controller will blink and then turn black.

Share:
35,742

Related videos on Youtube

Ian
Author by

Ian

Updated on July 05, 2022

Comments

  • Ian
    Ian almost 2 years

    The App Store app on iOS 7 uses a frosted glass-type effect where it is possible to see the view behind. Is this using an API built into iOS 7 or is it custom code. I was hoping it would be the former but I can't see any obvious references in the documentation. Obvious things like (like setting the alpha property on the modal view) don't seem to have any effect.

    To see an example, open the App Store app and press the button at the top-right.

    App Store home page Modal view in the App Store

    • Tà Truhoada
      Tà Truhoada over 8 years
      I like your question
    • gblazex
      gblazex over 8 years
      @Ian - you should accept Sebastian Hojas's answer
  • João Nunes
    João Nunes over 10 years
    and how can you keep the back ViewController while the modal is up? in my case the back VC goes away..
  • Brad G
    Brad G about 10 years
    Is presenting a view with animation, and backed by a UIToolbar view app store safe?
  • rckoenes
    rckoenes about 10 years
    You don't since the back viewController is just a frosted image on the modal viewcontroller.
  • OneManBand
    OneManBand about 10 years
    developer.apple.com/downloads/download.action?path=wwdc_2013‌​/… - A direct link to the Image Effects Category
  • Sebastian Hojas
    Sebastian Hojas almost 10 years
    @OneManBand Added the link. Thanks!
  • Vadoff
    Vadoff over 9 years
    This won't behave quite like the App Store's modal view controller which actually dynamically blurs what's underneath - including the animated featured apps.
  • David H.
    David H. over 9 years
    Does it work if the presenting view controller is a uinavigationcontroller??
  • c9s
    c9s about 9 years
    The overlay seems like will be added on the top view layer
  • Renfei Song
    Renfei Song almost 9 years
    Since iOS 8, there is finally a direct way to accomplish this effect via UIModalPresentationOverCurrentContext. See Andrew Plummer, mxcl and Andrey Konstantinov's answer below.
  • Crashalot
    Crashalot almost 9 years
    This doesn't stay blurred? Using the iOS 8 method, the background blurs on transition and shows the first view controller transparently, but the modal view controller turns black after it fully loads.
  • Crashalot
    Crashalot almost 9 years
    This doesn't stay blurred? Using the iOS 8 method, the background blurs on transition and shows the first view controller transparently, but the modal view controller turns black after it fully loads. – Crashalot just now edit
  • Andrew Plummer
    Andrew Plummer over 8 years
    @Crashalot did you change any settings like changing the UIModalPresentationOverCurrentContext to fullscreen?
  • Andrew Plummer
    Andrew Plummer over 8 years
    To add @Crashalot, if you don't use that modal presentation style it stops "showing" the VC underneath once the modal is up, hence it turns "black" (nothing underneath)
  • christijk
    christijk over 6 years
    What is mainButtonViewController?
  • Andrei Konstantinov
    Andrei Konstantinov over 6 years
    @christijk it should be fancyViewController (it is, now). Thank you for pointing out.