Search code examples
iosobjective-cuiblureffectuivisualeffectview

iOS 8 UIVisualEffect View with UIBlurEffect becomes opaque


I am trying to present a view with a blurred transparent background over an existing view. I am able to get the desired effect during the presentation animation, but once the blurred view is fully presented, it becomes opaque.

Here's how I am presenting it:

if (!UIAccessibilityIsReduceTransparencyEnabled()) {
    UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
    UIVisualEffectView *blurEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
    blurEffectView.frame = self.view.bounds;
    [blurEffectView setOpaque:NO];
    [self.view insertSubview:blurEffectView atIndex:0];
    [blurEffectView setTranslatesAutoresizingMaskIntoConstraints:false];
}

In my blurred view, I have set the background color to clear color and opaque to NO. Any thoughts?


Solution

  • I wound up writing a custom presentation controller. Never found a way to do this with standard presentations.

    In the view where I want the effect viewDidLoad:

    //Custom Modal Presentation
    [self setModalPresentationStyle:UIModalPresentationCustom];
    
    //blur the controlContainerView
    if (!UIAccessibilityIsReduceTransparencyEnabled()) {
    
        UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:[self blurStyle]];
        UIVisualEffectView *blurEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
        blurEffectView.frame = self.controlContainerView.bounds;
        [blurEffectView setOpaque:NO];
        [self.controlContainerView insertSubview:blurEffectView atIndex:0];
        [blurEffectView setTranslatesAutoresizingMaskIntoConstraints:false];
    }
    

    Invoking the above view:

    //in .h
    @property (nonatomic) id<UIViewControllerTransitioningDelegate> transitioningDelegate;
    
    //In .m
    BlurViewController *blurVC = [self.storyboard instantiateViewControllerWithIdentifier:@"blurView"];
    _transitioningDelegate = [[MyCustomOverlayDelegate alloc] init];
    [blurView setModalPresentationStyle:UIModalPresentationCustom];
    [blurView setTransitioningDelegate:[self transitioningDelegate]];
    [blurView setBlurStyle:UIBlurEffectStyleLight];
    [self presentViewController: blurView animated:YES completion:nil];
    

    You will also need to import the entire stack of presentation controller classes. For me, these were OverlayDelegate, OverlayTransitionAnimator, and OverlayPresentationController. This is where the real work is.

    If you can, check out WWDC 2014 session 228 "A look inside presentation controllers". Custom presentations are covered about half-way through. It was what I used to base my custom stack on and reasonably straight forward.