[英]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的背景。
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艺术品:/
我发现在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.