简体   繁体   English

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

[英]Create shadow around a UIVisualEffectView without covering the whole view

Is it possible to create a shadow around a UIVisualView with UIBlurEffect without letting the UIVisualView get coloured by the shadow underneath? 是否可以使用UIBlurEffect在UIVisualView周围创建阴影,而不让UIVisualView被下面的阴影着色?

I basically just want the shadow around the view but with this code the shadow will cover the whole view which darkens the whole view to much: 我基本上只想要视图周围的阴影,但是使用此代码,阴影将覆盖整个视图,使整个视图变暗:

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)

EDIT. 编辑。
I need to achieve the same thing as in Apple's Maps application. 我需要实现与Apple的Maps应用程序相同的功能。 Where the draggable favourite view both uses the UIVisualEffectView and a shadow around its top, without interfering with the UIVisualEffectView's background. 可拖动的收藏夹视图都使用UIVisualEffectView和顶部的阴影,而不会干扰UIVisualEffectView的背景。

See example screenshots: 查看示例屏幕截图: 在此输入图像描述 在此输入图像描述

Ok, so the problem was that my background in the underlying view was white. 好吧,问题是我在底层视图中的背景是白色的。 And with the UIBlurEffect .extraLight used on a background which is lighter than the BlurEffect the shadow beneath a UIVisualView appears darker than with a more vivid background. 由于UIBlurEffect .extraLight在比BlurEffect更亮的背景上使用,UIVisualView下方的阴影看起来比背景更鲜艳。

Also described in this question: 在这个问题中也有描述:
Fix UIVisualEffectView extra light blur being gray on white background 修复UIVisualEffectView额外的光模糊在白色背景上是灰色的

UPDATE UPDATE

I found a project explaining how to solve this on Github The solution involves creating a 9-part UIImage to represent the shadow. 我找到了一个解释如何在Github上解决这个问题的项目解决方案涉及创建一个9部分的UIImage来表示阴影。 The creator also explains the underlying layers of the iOS 10 Maps. 创建者还解释了iOS 10 Maps的底层。

So i'm trying to recreate the look of iOS 10 maps. 所以我试图重新创建iOS 10地图的外观。 I decided to attach the maps app in the simulator to the debugger to see what was going on... 我决定将模拟器中的地图应用程序附加到调试器,看看发生了什么......

查看调试器细分

Apple actually get around this by having a UIImage over the top of the content with the border and shadow. Apple实际上通过在边框和阴影的内容顶部使用UIImage来解决这个问题。 Not the most elegant way to do it but i'm going for the exact look so I'm going to take the exact approach. 这不是最优雅的方式,但我要准确的外观,所以我会采取确切的方法。

I also grabbed the asset (using this ) from the Maps app to save making your own one. 我还从地图应用程序中抓取了资产(使用此项 )以保存自己的资产。 Shame they only have @2x artwork in it though :/ 很遗憾,他们只有@ 2x艺术品:/

CardShadowFull@2x.png

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

The trick is to not set the shadowPath of the layer. 诀窍是不设置图层的shadowPath If it is set, the shadow is painted below the visual effect view and, in consequence, darkens the blurred view. 如果已设置,阴影将绘制在视觉效果视图下方,从而使模糊视图变暗。

The documentation for shadowPath states: 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. 如果为此属性指定值,则图层将使用指定的路径而不是图层的合成Alpha通道创建其阴影。

The "instead…" part is what we actually need: the shadow should be composed after rendering the content, based on what the content leaves transparent. “相反......”部分是我们实际需要的部分:阴影应该在渲染内容之后根据内容透明的内容进行组合。 Now you might be deterred from not setting a shadowPath because the documentation also states that an "explicit path usually improves rendering performance". 现在您可能无法设置shadowPath因为文档还指出“显式路径通常可以提高渲染性能”。 However, I didn't see any issues in real life so far. 但是,到目前为止我没有看到现实生活中的任何问题。 In comparison to the rendering cost of the UIVisualEffectView , painting the shadow doesn't make a difference, I assume. UIVisualEffectView的渲染成本UIVisualEffectView ,绘制阴影并没有什么区别,我假设。

Also make sure to set the shadow on a superview of the UIVisualEffectView , not on a sibling view. 还要确保在UIVisualEffectView视图上设置阴影,而不是在兄弟视图上。

I usually solve this kind of situation using composition of views. 我通常使用视图组合来解决这种情况。 Instead of setting the shadow in the target view, I create a ShadowView and I put it behind the target view, both views with the same frame. 我没有在目标视图中设置阴影,而是创建了一个ShadowView,并将其放在目标视图后面,两个视图都使用相同的框架。

I've posted and example and code in this question . 我在这个问题上发布了示例和代码。

An example of the result of this approach is the following: 这种方法的结果示例如下:

在此输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 TableView覆盖View中的整个屏幕 - TableView Covering up whole screen in View 使用UIVisualEffectView创建模糊视图,在模拟器上更正,但在iphone和ipad上没有 - use UIVisualEffectView to create a blur view, correct on simulator but not on iphone & ipad 如何使用覆盖整个视图的地图视图处理UIScreenEdgeGestureRecognizer? - How to handle a UIScreenEdgeGestureRecognizer with a map view covering the whole view? 使用模态视图控制器和UIVisualEffectView - Using Modal View Controllers and UIVisualEffectView 呈现模态视图控制器而不覆盖iPhone上的当前视图 - Presenting a modal view controller without covering the current view on iPhone 如何将阴影和圆角添加到 UIVisualEffectView? - How do I add both shadow and rounded corners to a UIVisualEffectView? 显示覆盖整个UITableView的标签 - Display a label covering the whole UITableView ui表格视图单元格重新排序*无*阴影 - ui table view cell reorder *without* shadow 替换情节提要中的UIVisualEffectView(或任何视图)的快速方法 - Quick way to replace UIVisualEffectView (or any view) in storyboard 如何从UIVisualEffectView和UIActivityIndi​​catorView创建新类 - How to create a new class from UIVisualEffectView and UIActivityIndicatorView
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM