iOS-毛玻璃效果详解

在ios开发过程中,为了界面的美观,我们往往需要对一个图片进行模糊化处理,有一种朦胧美得感觉,就是所谓的毛玻璃效果。在GitHub上不乏实现毛玻璃效果的三方框架,这里就不做过多介绍。现在主要谈谈苹果自己提供的两种实现毛玻璃效果的类,UIToolBar和UIVisuaEffectView。


UIToolBar

UIToolBar在IOS 2.0就已经出现,可以快速实现毛玻璃效果。简单易懂,但是效果单一,系统只提供了两种bayStyle. UIBarStyleDefault和UIBarStyleBlack 。

iOS-毛玻璃效果详解_第1张图片
Snip20160717_9.png
iOS-毛玻璃效果详解_第2张图片
Snip20160717_8.png
//背景图片
  UIImageView *backImageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"Snip20160714_17"]];
    backImageView.frame = self.view.bounds;
    [self.view addSubview:backImageView];
//UIToolBar:加了三层遮盖
        UIToolbar *bar = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 100,375, 300)];
        bar.barStyle = UIBarStyleDefault;
        bar.alpha = 0.8;
        [self.view addSubview:bar];

UIVisuaEffectView

UIVisuaEffectView是苹果从IOS8.0开始提供的可实现毛玻璃效果(blur)的控件。相比以前的UIToolBar,UIVisuaEffectView的功能更加强大,能实现更加复杂的效果。 利用UIVisuaEffectView实现毛玻璃效果,首先需要对UIVisualEffect,UIBlurEffect、UIVibrancyEffect 和UIVisuaEffectView有一个正确的认识:

  • 1.UIVisuaEffectView :继承自UIView,可以看成是专门用于处理毛玻璃效果的视图,只要我们将这个特殊的View添加到其他视图(eg. ImageView )上面,被该UIVisuaEffectView遮盖的部分看起来就有了毛玻璃效果。使用UIVisuaEffectView有一点需要特别注意,不要在UIVisuaEffectView实例化View上面直接添加subViews,应该将需要添加的子视图添加到其contentView上。同时,尽量避免将UIVisualEffectView对象的alpha值设置为小于1.0的值,因为创建半透明的视图会导致系统在离屏渲染时去对UIVisualEffectView对象及所有的相关的子视图做混合操作,比较消耗性能。

  • 2.UIBlurEffect:毛玻璃效果。使用该效果,会使得UIVisualEffectView下面的内容出现毛玻璃化,但是添加到contentView的View不会受影响。

  • 3.UIVibrancyEffect:生动效果。该效果,能够放大和调整放在UIVisualEffectView对象下面的内容的颜色,也能让添加在contentView中的内容变得更加生动。它可以放在一个配置了UIBlurEffect效果的UIVisualEffectView的上面或者作为其subView。这种效果仅仅对与添加到contentView中的内容有效果。因为这种生动效果依赖于颜色,添加到contentView中的subViews 需要实现tintColorDidChange方法,并及时更新。如果是UIImageView,必须设置其渲染方式为UIImageRenderingModeAlwaysTemplate。

  • 4. UIVisualEffect:一个视觉效果抽象类,继承自NSObject,是UIBlurEffect和UIVibrancyEffect的父类。
    具体代码和效果:
    利用UIVisuaEffectView实现毛玻璃效果,首先需要创建一个UIVisuaEffectView对象,同时给该对象指定一种处理效果(UIBlurEffect/UIVibrancyEffect)。

1). UIBlurEffect


//设置背景图片
UIImageView *backImageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"Snip20160714_17"]];

backImageView.frame = self.view.bounds;

[self.view addSubview:backImageView];

//设置UIVisualEffectView

UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];

UIVisualEffectView *visualView = [[UIVisualEffectView alloc]initWithEffect:blurEffect];

visualView.frame = CGRectMake(0, 100,375, 300);

[self.view addSubview:visualView];
//UIBlurEffect的effectWithStyle有三种:UIBlurEffectStyleExtraLight/UIBlurEffectStyleLight/UIBlurEffectStyleDark
iOS-毛玻璃效果详解_第3张图片
Snip20160717_1.png
iOS-毛玻璃效果详解_第4张图片
Snip20160717_3.png

可以看出使用UIBlurEffect 其实是在图片上面添加了三层遮盖。所以,如果图片放在了UIVisualEffectView的上面就没有效果。

2). UIVibrancyEffect

//设置背景图片
    UIImageView *backImageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"Snip20160714_17"]];
    backImageView.frame = self.view.bounds;
    [self.view addSubview:backImageView];
    //UIVisualEffectView
    UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
    UIVibrancyEffect *vibrancyEffect = [UIVibrancyEffect effectForBlurEffect:blurEffect];
    UIVisualEffectView *visualView = [[UIVisualEffectView alloc]initWithEffect:vibrancyEffect];
    UIView *redView = [[UIView alloc]init];
    redView.backgroundColor = [UIColor redColor];
    [visualView.contentView addSubview:redView];
    visualView.frame = CGRectMake(0, 100,375, 300);
    redView.frame = visualView.bounds;
    [self.view addSubview:visualView];

通过改变contentView中subView,可以实现不同更加生动的效果。

iOS-毛玻璃效果详解_第5张图片
Snip20160717_5.png
iOS-毛玻璃效果详解_第6张图片
Snip20160717_6.png

补充

  • 鉴于下面一位热心的朋友提示,自己就抽时间稍微看了一下Core Image相关的东西。Core Image是苹果提供的一个相当强大专门用于处理图片的库。稍微试了一下,不仅能实现毛玻璃效果,还能实现很多其他的效果。但是,在使用过程中发现使用Core Image来实现这些效果,非常占用内存。查看文档:createCGImage:outputImage : fromRect:方法会单独开辟一个临时的缓存区,出现离屏渲染,这可能是一个使得内存增大的重要原因。
render the region 'fromRect' of image 'image' into a temporary buffer using the context, then create and return a new CoreGraphics image with  the results.
  • 下面简单看下效果吧
#import "ViewController.h"

@interface ViewController ()
@property (strong, nonatomic) IBOutlet UIImageView *iconImageView;
@property (strong, nonatomic) IBOutlet UIImageView *blurImageVIew;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    //1.获取CIIamge对象
    CIImage * ciIamge = [CIImage imageWithCGImage:_iconImageView.image.CGImage];
//    //2.创建滤镜对象
    CIFilter *filter = [CIFilter filterWithName:@"CIMotionBlur"
                                  keysAndValues:kCIInputImageKey, ciIamge, nil];
    // 获取绘制上下文
    CIContext *context = [CIContext contextWithOptions:nil];
   // 渲染并输出CIImage
    CIImage *outputImage = [filter outputImage];
    // 创建CGImage句柄
    CGImageRef cgImage = [context createCGImage:outputImage
                                       fromRect:[outputImage extent]];
    self.blurImageVIew.image =[UIImage imageWithCGImage:cgImage];
    self.blurImageVIew.contentMode = UIViewContentModeScaleAspectFill;
    // 释放CGImage句柄
    CGImageRelease(cgImage);
//    self.blurImageVIew.image = self.iconImageView.image;
}

iOS-毛玻璃效果详解_第7张图片
Snip20160827_4.png
  • 未使用Core Image


    iOS-毛玻璃效果详解_第8张图片
    未使用.png
  • 使用Core Image

iOS-毛玻璃效果详解_第9张图片
使用Core Image.png
  • 其他效果。只需传入不同的滤镜的name,上面选择的是:CIMotionBlur 。具体可以选择的name 可以参考
    https://developer.apple.com/library/ios/documentation/GraphicsImaging/Reference/CoreImageFilterReference/index.html#//apple_ref/doc/filter/ci/CIMotionBlur

你可能感兴趣的:(iOS-毛玻璃效果详解)