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

Create shadow around a UIVisualEffectView without covering the whole view

是否可以使用 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 的背景。

查看示例截图:

好的,问题是我在底层视图中的背景是白色的。并且在比 BlurEffect 更亮的背景上使用 UIBlurEffect .extraLight 时,UIVisualView 下的阴影看起来比更生动的背景更暗。

在这个问题中也描述了:
Fix UIVisualEffectView extra light blur being gray on white background

更新

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

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

Apple 实际上通过在带有边框和阴影的内容顶部放置一个 UIImage 来解决这个问题。这不是最优雅的方式,但我想要精确的外观,所以我将采用精确的方法。

我还从地图应用程序中获取了资产(使用 this),以节省制作自己的资产。遗憾的是他们里面只有@2x 艺术品:/

我在iOS12中找到了,这不是问题,UIVisualEffectView忽略了下面视图的阴影,它只是看穿了阴影,就像阴影不存在一样。

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

shadowPath 的文档指出:

If you specify a value for this property, the layer creates its shadow using the specified path instead of the layer’s composited alpha channel.

"instead…" 部分是我们实际需要的部分:阴影应该在渲染内容之后根据内容留下的透明部分合成。现在您可能不敢不设置 shadowPath,因为文档还指出 "explicit path usually improves rendering performance"。但是,到目前为止,我在现实生活中没有看到任何问题。与 UIVisualEffectView 的渲染成本相比,我认为绘制阴影并没有什么不同。

还要确保在 UIVisualEffectView 的父视图上设置阴影,而不是在兄弟视图上设置阴影。

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

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

此方法的结果示例如下: