如何实现发光阴影?

How can I achieve luminescent shadows?

  1. 整个模型有一个阴影,让我想起了Philip's Ambilight TVs
  2. 查看 "Trailer and Photos" 部分所有图块都有这种类型的阴影。

这个效果真的很吸引人,我想把它整合到我的应用程序中。

这是我的想法:

  1. 截取视图并将其放大到 110%
  2. 将它放在视图后面。
  3. 模糊屏幕截图。
  4. 应用内部白色阴影。

有什么建议吗?

你的想法是正确的,但没有必要应用内阴影,可以在屏幕截图中添加透明插图,当模糊时,这将创建你正在寻找的渐变。

下面的代码应该可以完成这项工作:

- (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;
}