UIVisualEffectView

import Foundation
import UIKit

//
//  UIVisualEffectView.h
//  UIKit
//
//  Copyright (c) 2014-2016 Apple Inc. All rights reserved.
//

/* UIVisualEffectView is a class that provides a simple abstraction over complex visual effects. 
   Depending on the desired effect, the results may affect content layered behind the view or content added to the view's contentView. 
   Please see the notes for each UIVisualEffect for more details.

UIVisualEffectView 是一个类,它提供了一个简单的抽象复杂的视觉效果。根据预期的效果,结果可能会影响效果视图后面的内容 或者是 添加到效果视图的contentView中的内容。详细信息,请参阅每个UIVisualEffect的笔记。

 Proper use of this class requires some assistance on your part. Namely:
正确使用这个类的需要一些帮助

 • Avoid alpha values < 1 - By default, when a view is partially transparent, the system composites that view and all of its subviews in an offscreen render pass to get the correct translucency. However, UIVisualEffects require being composited as part of the content they are logically layered on top of to look correct. If alpha is less than 1 on the UIVisualEffectView or any of its superviews, many effects will look incorrect or won't show up at all. Setting the alpha on views placed inside the contentView is supported.
 * 避免 alpha 的值 小于 1。 当一个 view 是部分透明的时候,视图的 view 和 子view会在离屏渲染的时候来获取正确的透明度。然而,UIVisualEffects需要被合成为内容的一部分,他们在逻辑上是分层的正确。 如果UIVisualEffectView透明度小于1 或任何它的父视图的透明度小于1 ,许多影响会看起来不正确或根本不会出现。设置视图放置在contentView 透明度是支持。

 • Judicious masking - Masks have similar semantics to non-opaque views with regards to offscreen rendering. 
   Masks applied to the UIVisualEffectView itself are forwarded to all internal views, including the contentView.
   You are free to apply a mask to just the contentView. The mask you provide to UIVisualEffectView will not be the view that actually performs the mask. UIKit will make copies of the view to apply to each subview. 
   To reflect a size change to the mask, you must apply the change to the original mask view and reset it on the effect view. 
   Applying a mask to a superview of a UIVisualEffectView (via setMaskView: or the layer's mask property) will cause the effect to fail.
   谨慎的遮罩 - 

 • Correctly capturing snapshots - Many effects require support from the window that hosts the view. 
   As such, attempting to take a snapshot of just the UIVisualEffectView will result in the snapshot not containing the effect at all or it appearing incorrectly. To properly snapshot a view hierarchy that contains a UIVisualEffectView, you must snapshot the entire UIWindow or UIScreen that contains it.
   正确的获取快照 - 大多数的效果是需要主视图窗口的支持。因此,试着去获取 UIVisualEffectView 的截屏,可能截取到的视图是不会包含任何效果的,有可能出现显示错误。 为了正确的截取一个包含该 UIVisualEffectView 视图的的层级视图,你必须截取 UIWindow 或者 UIScreen 包含的内容。
 */

@available(iOS 8.0, *)

// 模糊效果样式枚举
public enum UIBlurEffectStyle : Int {

    // Creates a blurring effect in the view. The area of the view is lighter in hue than the underlying view.
    // 区域视图比下面的视图在色调更加的亮
    case extraLight

    // Creates a blurring effect in the view. The area of the view is the same approximate hue of the underlying view.
    // 区域视图和下面的视图在色调上近似
    case light

    // Creates a blurring effect in the view. The area of the view is darker in hue than the underlying view.
    // 区域视图和下面的视图在色调上更加的暗
    case dark

    

    // --------------  在 iOS10 可以用- 适应用户界面风格 ---------
    @available(iOS 10.0, *)
    case regular // Adapts to user interface style

    @available(iOS 10.0, *)
    case prominent // Adapts to user interface style
}



@available(iOS 8.0, *)
// 视觉效果
public class UIVisualEffect : NSObject, NSCopying, NSSecureCoding {
}



/* UIBlurEffect will provide a blur that appears to have been applied to the content layered behind the UIVisualEffectView. 
Views added to the contentView of a blur visual effect are not blurred themselves. 
UIBlurEffect 将给 UIVisualEffectView content layered 下面的视图产生一个模糊显示的效果。 
view 添加到 UIVisualEffectView 的 contentView 中是不会产生模糊效果的。
*/
@available(iOS 8.0, *)
// 模糊效果
public class UIBlurEffect : UIVisualEffect {

    public /*not inherited*/ init(style: UIBlurEffectStyle)
}

/* UIVibrancyEffect amplifies and adjusts the color of content layered behind the view, allowing content placed inside the contentView to become more vivid.
   UIVibrancyEffect 增强和调整 UIVibrancyEffect content layered 后面视图的颜色,会使在 contentView 中的内容变的更加的生动。

   It is intended to be placed over, or as a subview of, a UIVisualEffectView that has been configured with a UIBlurEffect. 
  UIVisualEffectView 作为一个 UIBlurEffect 的子视图被添加到 UIBlurEffect 上面。
    
   This effect only affects content added to the contentView. 
   这个效果只会影响添加到 contentView 中的内容。  

   Because the vibrancy effect is color dependent, subviews added to the contentView need to be tintColorDidChange aware and must be prepared to update themselves accordingly. 
   因为 vibrancy effect 的颜色依靠 添加到 contentView 中 subviews 的 tintColorDidChange 时时的更新自己。

   UIImageView will need its image to have a rendering mode of UIImageRenderingModeAlwaysTemplate to receive the proper effect.
  UIImageView 需要调整 image 的渲染模式为 UIImageRenderingModeAlwaysTemplate 来适应 vibrancy effect 的效果。
  
 */
@available(iOS 8.0, *)
// 视觉效果视图
public class UIVibrancyEffect : UIVisualEffect {

    public /*not inherited*/ init(blurEffect: UIBlurEffect)
}

@available(iOS 8.0, *)
// 高亮视觉效果视图
public class UIVisualEffectView : UIView, NSSecureCoding {

    // 内容视图(需要进行视觉效果处理的视图就添加到 content 中)
    public var contentView: UIView { get } // Do not add subviews directly to UIVisualEffectView, use this view instead.
    
    // 视觉效果(模糊和高亮)
    @NSCopying public var effect: UIVisualEffect?

    public init(effect: UIVisualEffect?)
    public init?(coder aDecoder: NSCoder)
}

iOS8 后,apple 开放的创建毛玻璃效果的接口。
创建一个UIVisualEffectView视图对象,这个对象提供了一种简单的方式来实现复杂的视觉效果,这个可以把这个对象看作是效果的一个容器。

  1. UIVisualEffectView实际的效果会影响到该视图对象底下的内容。
  2. UIVisualEffectView实际的效果会影响添加到该视图对象的contentView中的内容。

所有获得视觉效果有两种方式:

  1. 将 UIVisualEffectView 视图作为一个遮罩视图。透过遮罩视图,看到后面的视图就是模糊的。
  2. 将需要模糊处理的内容视图添加到 UIVisualEffectView 的 contentView 中,但是 UIVisualEffectView 视图后面的内容还是会受到影响,产生模糊效果。
使用的例图.png

override func viewDidLoad() {
     super.viewDidLoad()

     // 设置 view 的背景颜色(其实就是设置背景视图) 
     self.view.backgroundColor = UIColor(patternImage: UIImage(named: "Snip20160725_3")!)
    
    //  效果视图(效果为模糊)
    let effectView = UIVisualEffectView(effect: UIBlurEffect(style: .extraLight))
    effectView.frame = CGRect(x: 10, y: 100, width: 300, height: 100)

    // 设置透明度
    effectView.alpha = 0.5
    view.addSubview(effectView)
}

Snip20160725_4.png
//  值在 0 到 1 之间。  值越大 越模糊(底部的内容越看不清)
effectView.alpha = 0.5     

UIVisualEffectView 的 contentView 添加需要模糊内容的效果

override func viewDidLoad() {
    super.viewDidLoad()
    
    self.view.backgroundColor = UIColor(patternImage: UIImage(named: "Snip20160725_3")!)
    
    let tempView = UIView()
    tempView.frame = CGRect(x: 0, y: 0, width: 250, height: 150)
    tempView.backgroundColor = UIColor(patternImage: UIImage(named: "Snip20160725_3")!)

    let effectView = UIVisualEffectView(effect: UIBlurEffect(style: .extraLight))
    effectView.frame = CGRect(x: 10, y: 100, width: 300, height: 100)
    effectView.alpha = 0.5

    // 添加需要模糊的内容
    effectView.contentView.addSubview(tempView)
    view.addSubview(effectView)
}
Snip20160725_5.png

注意点:

  1. 不应该直接添加子视图到UIVisualEffectView视图中,而是应该添加到UIVisualEffectView对象的contentView中。
  2. 尽量避免将UIVisualEffectView对象的alpha值设置为小于1.0的值,因为创建半透明的视图会导致系统在离屏渲染时去对UIVisualEffectView对象及所有的相关的子视图做混合操作。这不但消耗CPU/GPU,也可能会导致许多效果显示不正确或者根本不显示。(**我们可以调整 contentView 的 透明度的值 **)

UIVisualEffect

UIVisualEffect 是一个集成自 NSObject 的基类。
两个子类:
| -- UIBlurEffect (模糊效果)
| -- UIVibrancyEffect (在模糊效果上实现特殊效果)

  • 一个UIBlurEffect对象用于将blur(毛玻璃)效果应用于UIVisualEffectView视图下面的内容。如上面的示例所示。不过,这个对象的效果并不影响UIVisualEffectView对象的contentView中的内容。
  • UIVibrancyEffect主要用于放大和调整UIVisualEffectView视图下面的内容的颜色,同时让UIVisualEffectView的contentView中的内容看起来更加生动。(可以理解为在毛玻璃上滴了一滴水,用水在毛玻璃上进行写字。 写字的效果就是 UIVibrancyEffect 效果的简单使用

通常UIVibrancyEffect对象是与UIBlurEffect一起使用,主要用于处理在UIBlurEffect特效上的一些显示效果。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容