我试图复制苹果公开发布的iOS 7示例屏幕上的模糊背景:

这个问题建议对下面的内容应用CI过滤器,但这是一个完全不同的方法。很明显,iOS 7并没有捕捉到下面视图的内容,原因有很多:

做一些粗略的测试,截取以下视图的截图,并应用CIGaussianBlur过滤器,使用足够大的半径来模拟iOS 7的模糊风格,即使在模拟器上也需要1-2秒。 iOS 7的模糊视图能够模糊动态视图,比如视频或动画,没有明显的延迟。

有没有人可以假设他们可以使用什么框架来创建这种效果,以及是否有可能使用当前的公共api创建类似的效果?

编辑:(来自评论)我们不知道苹果是怎么做的,但我们能做出一些基本的假设吗?我们可以假设他们在使用硬件,对吧?

效果是否在每个视图中都是自包含的,以至于效果实际上不知道它背后是什么?或者,基于模糊的工作原理,模糊背后的内容必须被考虑进去?

如果效果背后的内容是相关的,我们是否可以假设苹果正在接收以下内容的“feed”,并不断地以模糊的方式渲染它们?


当前回答

我写了UIView的子类它能在任何自定义视图上产生原生ios7模糊。它使用UIToolbar,但以一种安全的方式改变它的帧,边界,颜色和alpha实时动画。

如果你发现任何问题请告诉我。

https://github.com/ivoleko/ILTranslucentView

其他回答

您可以尝试使用我的自定义视图,它具有模糊背景的功能。它通过假装拍摄背景快照并模糊它来做到这一点,就像苹果的WWDC代码中那样。使用起来很简单。

我还做了一些改进,在不损失性能的情况下伪造动态模糊。我的视图的背景是一个scrollView,它与视图一起滚动,从而为父视图的其余部分提供了模糊效果。

请参阅我的GitHub上的示例和代码

Apple released code at WWDC as a category on UIImage that includes this functionality, if you have a developer account you can grab the UIImage category (and the rest of the sample code) by going to this link: https://developer.apple.com/wwdc/schedule/ and browsing for section 226 and clicking on details. I haven't played around with it yet but I think the effect will be a lot slower on iOS 6, there are some enhancements to iOS 7 that make grabbing the initial screen shot that is used as input to the blur a lot faster.

直接链接:https://developer.apple.com/downloads/download.action?path=wwdc_2013/wwdc_2013_sample_code/ios_uiimageeffects.zip

为什么要麻烦地复制这种效果呢?在你的视图后面画一个UIToolbar。

myView.backgroundColor = [UIColor clearColor];
UIToolbar* bgToolbar = [[UIToolbar alloc] initWithFrame:myView.frame];
bgToolbar.barStyle = UIBarStyleDefault;
[myView.superview insertSubview:bgToolbar belowSubview:myView];

事实上,我敢打赌这很容易实现。它的运作方式或外观可能不会完全像苹果,但可能非常接近。

首先,你需要确定你要呈现的UIView的CGRect。一旦确定了这一点,就只需要获取UI部分的图像,以便对其进行模糊处理。就像这样……

- (UIImage*)getBlurredImage {
    // You will want to calculate this in code based on the view you will be presenting.
    CGSize size = CGSizeMake(200,200);

    UIGraphicsBeginImageContext(size);
    [view drawViewHierarchyInRect:(CGRect){CGPointZero, w, h} afterScreenUpdates:YES]; // view is the view you are grabbing the screen shot of. The view that is to be blurred.
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    // Gaussian Blur
    image = [image applyLightEffect];

    // Box Blur
    // image = [image boxblurImageWithBlur:0.2f];

    return image;
}

高斯模糊-推荐

使用苹果提供的UIImage+ImageEffects Category,你会得到一个高斯模糊,看起来很像iOS 7中的模糊。

盒子模糊

你也可以使用下面的boxBlurImageWithBlur: UIImage类别来使用框模糊。这是基于你可以在这里找到的算法。

@implementation UIImage (Blur)

-(UIImage *)boxblurImageWithBlur:(CGFloat)blur {
    if (blur < 0.f || blur > 1.f) {
        blur = 0.5f;
    }
    int boxSize = (int)(blur * 50);
    boxSize = boxSize - (boxSize % 2) + 1;

    CGImageRef img = self.CGImage;

    vImage_Buffer inBuffer, outBuffer;

    vImage_Error error;

    void *pixelBuffer;

    CGDataProviderRef inProvider = CGImageGetDataProvider(img);
    CFDataRef inBitmapData = CGDataProviderCopyData(inProvider);

    inBuffer.width = CGImageGetWidth(img);
    inBuffer.height = CGImageGetHeight(img);
    inBuffer.rowBytes = CGImageGetBytesPerRow(img);

    inBuffer.data = (void*)CFDataGetBytePtr(inBitmapData);

    pixelBuffer = malloc(CGImageGetBytesPerRow(img) * CGImageGetHeight(img));

    if(pixelBuffer == NULL)
        NSLog(@"No pixelbuffer");

    outBuffer.data = pixelBuffer;
    outBuffer.width = CGImageGetWidth(img);
    outBuffer.height = CGImageGetHeight(img);
    outBuffer.rowBytes = CGImageGetBytesPerRow(img);

    error = vImageBoxConvolve_ARGB8888(&inBuffer, &outBuffer, NULL, 0, 0, boxSize, boxSize, NULL, kvImageEdgeExtend);

    if (error) {
        NSLog(@"JFDepthView: error from convolution %ld", error);
    }

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef ctx = CGBitmapContextCreate(outBuffer.data,
                                         outBuffer.width,
                                         outBuffer.height,
                                         8,
                                         outBuffer.rowBytes,
                                         colorSpace,
                                         kCGImageAlphaNoneSkipLast);
    CGImageRef imageRef = CGBitmapContextCreateImage (ctx);
    UIImage *returnImage = [UIImage imageWithCGImage:imageRef];

    //clean up
    CGContextRelease(ctx);
    CGColorSpaceRelease(colorSpace);

    free(pixelBuffer);
    CFRelease(inBitmapData);

    CGImageRelease(imageRef);

    return returnImage;
}

@end

现在你正在计算要模糊的屏幕区域,将它传递到模糊类别中,并接收一个已经模糊的UIImage,现在剩下的就是将这个模糊的图像设置为你将呈现的视图的背景。就像我说的,这将不是一个完美的匹配苹果正在做的,但它仍然看起来很酷。

希望能有所帮助。

iOS8回答了这些问题。

- (instancetype)initWithEffect:(UIVisualEffect *)effect

或迅速:

初始化(效果效果:UIVisualEffect)