APP中视图特殊效果的实现(一) —— 基于UIVisualEffectView的模糊效果的实现(一)

版本记录

版本号 时间
V1.0 2018.08.23

前言

很多时候我们APP中需要模糊等特殊效果的实现,前面我写过关于这样的文章,但是已经记不起来是哪一篇了,接下来几篇我们就专注关于模糊等特殊效果的实现。

开始

本篇您将学习如何在自己的应用程序中添加内置于iOS的漂亮模糊效果,以及了解诸如vibrancy等先进技术,以及模糊技术在技术层面的工作方式。

本文写作环境:Swift 4, iOS 11, Xcode 9

自从iOS 7的设计在iOS 7中发生了巨大的变化以来,模糊已经在应用程序设计中发挥了重要作用。 如果使用得当,模糊可以显着改善应用程序的可用性和外观。

让我们来看看Apple如何在系统级别使用模糊。 其中一个最值得注意的例子是控制中心。 模糊的背景保留了操作的上下文 - 控制中心不是自己的应用程序,但是面板显示在活动应用程序上方。

通知中心也使用此效果,但每个Notification Center扩展或通知都有自己模糊的背景,而不是模糊整个背景。 除了看起来很漂亮外,这种模糊可以帮助每个元素脱颖而出。

那么如何在自己的应用程序中重新创建这些类型的模糊? 使用内置的UIVisualEffectView! 在这个UIVisualEffectView教程中,您将学习使用模糊技巧使您的应用脱颖而出所需的一切。


Clear Facts on Blurs - 关于模糊的明确事实

以高雅和高效的方式执行模糊需要一些技巧。 在本节中,您将了解用于创建模糊效果的常用算法。

1. How Blurs Work - Blurs原理

所有模糊都以图像开始。 要实现模糊,可以对图像中的每个像素应用模糊算法; 然后,生成的图像包含原始图像的均匀模糊版本。 模糊算法的风格和复杂程度各不相同,但在本节中我们将研究一种称为高斯模糊(Gaussian blur)的常见算法。

模糊算法通常检查图像的每个像素并使用周围像素来计算该像素的新颜色值。 例如,考虑以下理论图像网格:

上述网格中的每个单元表示单个像素,并且每个像素具有介于1和10之间的值。考虑算法正在评估中心像素的情况。 该算法平均周围像素的值并将此平均值插入中心像素,从而产生以下新像素网格:

然后,对原始图像中的每个像素重复此过程。
上面的示例算法仅检查每个方向上的一个像素以创建新的平均值。 您可以进一步扩展此模糊半径以增加图像中的模糊量,如下图所示:

3px and 16px Gaussian Blur applied to an image

注意:通常,模糊半径越大,处理图像所需的处理能力就越大。 iOS将大多数图像处理活动给到GPU处理以保持主线程可以处理别的事情。

2. Blur Design Strategies - 模糊设计策略

人类倾向于关注焦点中的元素而忽略那些不重要的元素。 不管你是否相信,这是我们眼睛工作的自然结果。 当物体靠近或远离眼睛移动时,聚焦物体称为调节(accommodation); 它可以帮助您感知周围物体的深度和距离。

应用程序设计人员利用这一事实,模糊屏幕上不重要的项目,引导用户注意剩余的非模糊元素,如流行的Twitter客户端Tweetbot的屏幕截图所示:

后面的用户界面在上图中几乎无法识别。 这为用户提供了关于他们在导航层次结构中的位置的上下文感知(contextual awareness)。 例如,一旦您选择了其中一个显示的帐户,您就会期望在后台返回模糊视图。

注意:在移动应用程序中过度使用模糊要小心。 虽然模糊可以提供漂亮的效果,但如果使用不当或太频繁,它们可能会分散注意力并使人烦恼。遵循标准设计方法,使用模糊来引导用户注意重要的事情,你很少会出错。 有关此主题的更多信息,请参阅Apple iOS开发人员中心的iOS人机界面指南文档中的Designing for iOS部分。

下面看一下示例工程。

该应用程序向用户显示童话库。 当用户点击童话故事时,该应用程序会在屏幕上显示完整的故事。 用户可以自定义白天或夜间阅读的显示字体,文本对齐,甚至颜色主题。

在Xcode中打开Grimm.xcodeproj,打开Main.storyboard,看一下App中的view controllers,如下所示:

您可以忽略上图中的第一个视图控制器,因为它只是应用程序的根导航控制器。 依次看下每个编号的视图控制器,您将看到以下内容:

  • 1)第一个视图控制器是StoryListController,它显示数据库中所有童话的列表。
  • 2)点击列表中的故事会将segue到StoryViewController,后者显示所选童话的标题和文本。
  • 3)OptionsController包含在StoryViewController中,并显示可用的字体,文本对齐方式和颜色选项。 要显示它,只需点击细节控制器中的右上角椭圆图标。

Build并运行。 您将看到如下所示的初始屏幕:

探索这个应用程序很有意思,选择不同的故事,点击省略号图标并滑动到不同的字体和阅读模式,以了解用户界面的功能。

一旦掌握了应用的行为方式,请直接进入下一部分,了解如何将模糊效果应用于应用。


Blur Effects using UIVisualEffectView - 使用UIVisualEffectView实现模糊效果

UIKit提供了一整套视觉效果的好东西。 UIBlurEffectUIVisualEffect的子类,与您的兴趣特别相关。 UIBlurEffect提供了您在导航栏,通知中心和控制中心中看到的漂亮模糊 - 您也可以在应用中使用它。

1. Adding a UIBlurEffect - 添加一个UIBlurEffect

在这个项目中,您将使用blur来使OptionsController在故事的顶部上脱颖而出。

打开OptionsController.swift并将以下代码添加到viewDidLoad的末尾:

// 1
view.backgroundColor = .clear
// 2
let blurEffect = UIBlurEffect(style: .light)
// 3
let blurView = UIVisualEffectView(effect: blurEffect)
// 4
blurView.translatesAutoresizingMaskIntoConstraints = false
view.insertSubview(blurView, at: 0)

下面进行详细分解:

  • 1)为了使UIVisualEffectView实际模糊内容,其superview必须是透明的。 为此,您需要更改背景颜色以使其清晰。
  • 2)使用UIBlurEffectStyle.light样式创建UIBlurEffect。 这定义了使用什么样的模糊。 其他可用的样式是.extraLight.dark.extraDarkregularprominent
  • 3)使用刚创建的模糊创建UIVisualEffectView。 这个类是UIView的子类; 它的唯一目的是定义和显示复杂的视觉效果。
  • 4)禁止将自动调整大小的蒙版转换为blurView上的约束 - 您将在短时间内手动添加约束 - 并将其添加到视图堆栈的底部。 如果你刚刚在视图顶部添加了blurView,它最终会模糊其下面的所有控件!

现在,您需要确保您的blurView与视图的其余部分正确布局。

将以下代码添加到viewDidLoad的末尾:

NSLayoutConstraint.activate([
  blurView.heightAnchor.constraint(equalTo: view.heightAnchor),
  blurView.widthAnchor.constraint(equalTo: view.widthAnchor),
  ])

这些约束使blurView的frame与OptionsController视图保持一致。

Build并运行。 选择一个童话故事,点击省略号按钮,然后滚动文本。 随着模糊实时更新。

您现在在应用中拥有动态模糊效果,不仅易于实现,而且看起来也很棒。

2. Adding Vibrancy to your Blur - 为你的模糊添加Vibrancy

模糊效果很棒 - 但是像往常一样,Apple已经使用UIVibrancyEffect将其提升到了一个新的水平,当与UIVisualEffectView结合使用时,它会调整内容的颜色,使其更加生动。

下图演示了如何使您的标签和图标从屏幕上弹出,同时与背景本身混合:

图像的左侧显示正常的label和button,而右侧显示应用了vibrancy的label和button。

注意:必须将UIVibrancyEffect添加到已使用UIBlurEffect对象设置和配置的UIVisualEffectViewcontentView中;否则,不会有任何模糊效果!

打开OptionsController.swift并将以下代码添加到viewDidLoad的末尾

// 1
let vibrancyEffect = UIVibrancyEffect(blurEffect: blurEffect)
// 2
let vibrancyView = UIVisualEffectView(effect: vibrancyEffect)
vibrancyView.translatesAutoresizingMaskIntoConstraints = false
// 3
vibrancyView.contentView.addSubview(optionsView)
// 4
blurView.contentView.addSubview(vibrancyView)

下面进行详细解析:

  • 1)创建一个UIVibrancyEffect,它使用您之前设置的blurEffectUIVibrancyEffectUIVisualEffect的另一个子类。
  • 2)创建一个UIVisualEffectView以包含活力(vibrancy)效果。 此过程与创建blur完全相同。 由于您使用的是自动布局,因此请务必在此处禁用自动调整大小的转换。
  • 3)添加optionsView作为您的活力视图的contentView的子视图; 这可确保将活力效果应用于包含所有控件的视图。
  • 4)最后,将活力视图添加到模糊视图的contentView以完成效果。

接下来,您需要为活力视图设置自动布局约束,使其具有与模糊视图相同的尺寸,并使选项视图在活力视图中居中。

viewDidLoad的末尾添加以下约束:

NSLayoutConstraint.activate([
  vibrancyView.heightAnchor.constraint(equalTo: blurView.contentView.heightAnchor),
  vibrancyView.widthAnchor.constraint(equalTo: blurView.contentView.widthAnchor),
  vibrancyView.centerXAnchor.constraint(equalTo: blurView.contentView.centerXAnchor),
  vibrancyView.centerYAnchor.constraint(equalTo: blurView.contentView.centerYAnchor)
  ])

NSLayoutConstraint.activate([
  optionsView.centerXAnchor.constraint(equalTo: vibrancyView.contentView.centerXAnchor),
  optionsView.centerYAnchor.constraint(equalTo: vibrancyView.contentView.centerYAnchor),
  ])

在这个起作用之前你还有一件事要做。 如果你查看viewDidLoad的开头,你已经将optionsView添加为子视图 - 并且视图只能有一个superview。

在viewDidLoad的开头,注释掉以下代码:

view.addSubview(optionsView)
      
NSLayoutConstraint.activate([
  view.centerXAnchor.constraint(equalTo: optionsView.centerXAnchor),
  view.centerYAnchor.constraint(equalTo: optionsView.centerYAnchor)
  ])

Build并运行。 打开选项视图以查看您的新活力效果:

除非您具有高对比度视觉,否则活力效果使得阅读标签和控件变得非常困难。 这是怎么回事?

啊 - 模糊视图背后的内容很浅,你正在应用UIBlurEffectStyle.light效果。 可以肯定的是,这会适得其反。

修改viewDidLoad顶部附近初始化blurEffect的行:

let blurEffect = UIBlurEffect(style: .dark)

这会更改模糊效果,以在背景和文本之间添加更多对比度。

Build并运行。 你现在正在经历一些真正的活力:

3. Accessibility

说到模糊,最后还有一件事需要考虑:如果用户禁用模糊怎么办?

在模拟器或设备上,打开Settings应用,转到General\Accessibility\Increase Contrast,然后启用Reduce Transparency。 返回应用程序,再次打开选项视图。

嗯,这根本不起作用! 在这种情况下,回到你刚开始的是一个更好的选择。

幸运的是,您可以使用UIAccessibilityIsReduceTransparencyEnabled()检查是否启用了此辅助功能设置。 如果您知道此设置已启用,则可以更改应用的外观和行为方式。

使用之前注释掉的代码,在viewDidLoad中设置视图的背景颜色之前添加以下内容:

guard UIAccessibilityIsReduceTransparencyEnabled() == false else {
  view.addSubview(optionsView)
      
  NSLayoutConstraint.activate([
    view.centerXAnchor.constraint(equalTo: optionsView.centerXAnchor),
    view.centerYAnchor.constraint(equalTo: optionsView.centerYAnchor)
    ])
      
  return
}

此代码检查是否启用了Reduce Transparency。 如果是,您将忽略刚刚编写的所有代码并返回原始布局而不会出现任何模糊。

Build并运行应用程序,您将看到选项菜单再次显示正常。

您已经了解了如何模糊图像,以及如何使用UIVisualEffectView创建实时模糊效果。 您可以轻松地将高级模糊效果添加到您自己的应用程序中! 您可以深入了解更多的效果和选项,继续探索可参考Apple’s official UIVisualEffectView documentation

后记

本篇主要讲述了基于UIVisualEffectView的模糊效果的实现,感兴趣的给个赞或者关注~~~

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

推荐阅读更多精彩内容