在UIVisualEffectView周围创建阴影而不覆盖整个视图

时间:2016-10-05 23:56:15

标签: ios swift shadow uivisualeffectview uiblureffect

是否可以使用UIBlurEffect在UIVisualView周围创建阴影,而不让UIVisualView被下面的阴影着色?

我基本上只想要视图周围的阴影,但是使用此代码,阴影将覆盖整个视图,使整个视图变暗:

let borderPath = UIBezierPath(roundedRect: view.bounds, byRoundingCorners: [.topLeft, .topRight], cornerRadii: CGSize(width: 15, height: 15)).cgPath

shadowView.frame = view.bounds
shadowView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
shadowView.layer.shadowOpacity = 0.3
shadowView.layer.shadowRadius = 3.0
shadowView.backgroundColor = UIColor.clear

shadowView.layer.shadowPath = borderPath
shadowView.layer.shadowOffset = CGSize(width: 0, height: 0)
self.view.insertSubview(shadowView, at: 0)

let blurEffect = UIBlurEffect(style: .extraLight)
let blurView = UIVisualEffectView(effect: blurEffect)
blurView.frame = view.bounds
blurView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
blurView.clipsToBounds = true
blurView.layer.cornerRadius = 15
view.insertSubview(blurView, aboveSubview: shadowView)

修改
我需要实现与Apple的地图应用程序相同的功能。可拖动的收藏夹视图都使用UIVisualEffectView和顶部的阴影,而不会干扰UIVisualEffectView的背景。

参见示例屏幕截图: enter image description here enter image description here

5 个答案:

答案 0 :(得分:4)

好的,问题是我在底层视图中的背景是白色的。由于UIBlurEffect .extraLight在比BlurEffect更亮的背景上使用,UIVisualView下面的阴影看起来比背景更鲜艳。

此问题中也有描述:
Fix UIVisualEffectView extra light blur being gray on white background

<强>更新

我找到了一个项目,解释了如何在Github上解决这个问题。该解决方案涉及创建一个9部分的UIImage来表示阴影。创建者还解释了iOS 10 Maps的底层。

答案 1 :(得分:2)

我在iOS 12中发现这不是问题,UIVisualEffectView忽略了视图下方的阴影,它只是通过阴影看到了,就像阴影不存在一样。

答案 2 :(得分:1)

所以我试图重新创建iOS 10地图的外观。我决定将模拟器中的地图应用程序附加到调试器,看看发生了什么......

View debugger breakdown

苹果实际上通过在边框和阴影的内容顶部使用UIImage来解决这个问题。这不是最优雅的方式,但我要准确的外观,所以我会采取确切的方法。

我还从地图应用中抓取了资产(使用this)以保存自己的资产。很遗憾,他们只有@ 2x艺术品:/

CardShadowFull@2x.png

答案 3 :(得分:0)

诀窍是不设置图层的shadowPath。如果已设置,则阴影将被绘制在视觉效果视图的下方,从而使模糊的视图变暗。

shadowPath的文档说明:

  

如果为此属性指定一个值,则图层将创建其阴影   使用指定的路径而不是图层的合成Alpha   频道。

“真正的……”部分正是我们真正需要的:在渲染内容之后,应根据内容保持透明的内容来组成阴影。现在您可能会因为没有设置shadowPath而被阻止,因为文档还指出“显式路径通常可以提高渲染性能”。但是,到目前为止,我还没有看到现实生活中的任何问题。我认为,与UIVisualEffectView的渲染成本相比,绘制阴影没有区别。

还要确保将阴影设置在UIVisualEffectView的超级视图上,而不是在同级视图上。

答案 4 :(得分:0)

我通常使用视图组合来解决这种情况。我没有在目标视图中设置阴影,而是创建了ShadowView并将其放置在目标视图的后面,两个视图的框架相同。

我已经在this question中发布了示例和代码。

这种方法的结果示例如下:

enter image description here