This effect is truly fascinating to watch and I'd like to incorporate it into my app.
Here's what I've thought:
Any suggestions?
Your thoughts are correct, but there is no need to apply inner shadow, it's possible to add transparent insets to the screenshot, and when blurred, that would create gradient you're looking for.
The following code should do the job:
- (void)addLuminescentShadowToView:(UIView*)contentView
{
//the bigger radius of the blur
//the more spread shadow will get
CGFloat blurRadius = 15.0f;
//in order to shadow becomes transparent on edeges
//we're adding some transparent insets to the snapshot
CGFloat insetsSize = 2.0f * blurRadius;
//getting superview of content view
//it's important to do it before getting snapshot
//as during snapshot parent of the content view
//might be temporary changed
//superview will be used later to insert shadow
UIView* contentViewSuperview = contentView.superview;
//code for following methods were sourced from
//http://code.tutsplus.com/tutorials/adding-blur-effects-on-ios--cms-21488 and modified
//taking snapshot of content view
//method is modified to add transparent insets to the snapshot
UIImage* snapshot = [self takeSnapshotOfView: contentView withTransparentInsets: insetsSize];
//applying blur to the snapshot
UIImage* blurredSnapshot = [self blurWithCoreImage: snapshot
withRadius: blurRadius];
//creating view that displays shadow
UIImageView* shadowView = [[UIImageView alloc] initWithImage: blurredSnapshot];
shadowView.center = contentView.center;
//you could control appearence of the effect by modifying scale and alpha as well
//scale is not uniform to prevent spreading of the shadow by height, as shown on your example
shadowView.transform = CGAffineTransformMakeScale(1.05f, 0.95f);
shadowView.alpha = 1.0f;
//inserting shadow below content
[contentViewSuperview insertSubview:shadowView belowSubview:contentView];
}
- (UIImage *)takeSnapshotOfView:(UIView *)view withTransparentInsets:(CGFloat)insets
{
//creating bitmap context
CGRect contextRect;
contextRect.origin = CGPointZero;
contextRect.size = CGSizeMake(view.frame.size.width + 2.0f * insets, view.frame.size.height + 2.0f * insets);
UIGraphicsBeginImageContext(contextRect.size);
CGContextClearRect(UIGraphicsGetCurrentContext(), contextRect);
//rendering views hierarchy to the context
[view drawViewHierarchyInRect:CGRectMake(insets, insets, view.frame.size.width, view.frame.size.height) afterScreenUpdates:YES];
//getting result image
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
- (UIImage *)blurWithCoreImage:(UIImage *)sourceImage withRadius:(CGFloat)radius
{
CIImage *inputImage = [CIImage imageWithCGImage:sourceImage.CGImage];
//apply gaussian blur filter
CIFilter *gaussianBlurFilter = [CIFilter filterWithName: @"CIGaussianBlur"];
[gaussianBlurFilter setValue: inputImage forKey:@"inputImage"];
[gaussianBlurFilter setValue: @(radius) forKey:@"inputRadius"];
CIContext *context = [CIContext contextWithOptions:nil];
//creating output UIImage
CGImageRef cgImage = [context createCGImage:gaussianBlurFilter.outputImage fromRect:[inputImage extent]];
UIImage* outputImage = [UIImage imageWithCGImage:cgImage scale:1.0f orientation:UIImageOrientationUp];
CFRelease(cgImage);
return outputImage;
}