Search code examples
iosobjective-cios7uiimageuipopovercontroller

How to create a mask image for a screenshot when simulating blur effect for a popover


I have successfully implemented a blur effect for my app running on iPhone running iOS 7. I used the sample code Apple supplied with their UIImage+ImageEffects category. When I present a modal presentation, I take a screenshot in prepareForSegue and apply the effect, then pass that UIImage to the destinationViewController. In viewDidLoad of that new view controller, I simply set the background to be that of the stored image.

//prepareForSegue
UIImage *imageOfUnderlyingView = [UIImage snapshotImageWithView:[[UIApplication sharedApplication] keyWindow]];
destinationVC.imageOfUnderlyingView = [imageOfUnderlyingView applyBlurWithRadius:15
                                                                       tintColor:[UIColor redColor]
                                                           saturationDeltaFactor:1.2
                                                                       maskImage:nil];

//category method to take the snapshot
+ (UIImage *)snapshotImageWithView:(UIView *)view {
    UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0f);
    [view drawViewHierarchyInRect:view.bounds afterScreenUpdates:NO];
    UIImage *snapshotImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return snapshotImage;
}

//viewDidLoad on the presented view controller
self.tableView.backgroundView = [[UIImageView alloc] initWithImage:self.imageOfUnderlyingView];

This works really well because the view controller I present is full-screen, so the entire screen can be blurred and applied to the background. But now that I am optimizing the app for iPad, this isn't working because I no longer present the view controller full-screen but rather as a popover (or still modally but as a Form Sheet). In this case, the snapshot image shrinks and stretches to fit in the popover, which renders the effect useless because it doesn't show what is behind the popover but rather a snapshot of the entire screen which is very odd-looking.

My question is, how can I simulate a blur effect of the underlying view when presenting a popover, correctly only showing what is behind the popover, not shrinking the entire screen to fit in the popover?

I noticed there is a maskImage one can pass into the the method to generate the effect. How could I create a mask that cuts out the proper area for the popover? Or perhaps another approach would be to change the way in which it adjusts the image to fit such that it doesn't shrink but rather is overlaid without resizing, therefore only showing the proper area and hiding the rest of the image, if that would be possible. Or any other approach, anything to make it work. :)

Note that I will use the iOS 8 native API to achieve this effect in the future but I would like to simulate it now to work with iOS 7.


Solution

  • I ultimately decided what I want to achieve would be near impossible, because upon rotating the device the popover would relocate so different UI would lie underneath it, and navigating in this popover could resize the popover as well. So I decided if it's an iPad running iOS 7 then it just gets a solid background color.

    But if it's an iPad running iOS 8, then I support the native UIBlurEffect API which is really nice. :)