快速提示:向UIView添加圆角和阴影

为什么看似简单的事情很难

背景故事

我已经在一个应用程序上工作了几年,并且收到了一个简单的设计请求:在视图上四处拐角并添加阴影。 容易吧?

  //设置拐角半径 
layer.cornerRadius = 6.0
layer.masksToBounds = true
//设置阴影属性
layer.shadowColor = UIColor.black.cgColor
layer.shadowOffset = CGSize(宽度:0,高度:1.0)
layer.shadowOpacity = 0.2
layer.shadowRadius = 4.0

错误!
如果您以前尝试过此方法,那么您将确切知道会发生什么。 角将变圆,但阴影将消失。 如果将masksToBounds设置为false,则将显示阴影,但不会对角进行圆化。

CALayerWhyAreYouDoingThisToMe

事后看来, layer.masksToBounds = true的原因实际上是显而易见的,它会layer.masksToBounds = true该图层之外的所有内容。 阴影将在图层外部绘制,因此也会被剪切。 因此,我们不能对这两种效果使用同一层。

解决方案

我将分享我发现阻力最小的路径。 我选择创建一个固定在父view边缘的内部containerView 。 阴影将应用于父view的图层,而圆角将应用于containerView 。 然后,只需将所有内容添加到containerView

我敢肯定,也可以使用子图层和蒙版来完成此操作,但是使用AutoLayout时会遇到一些麻烦,因为我们不知道布局时视图的大小。 这将需要覆盖视图控制器中的layoutSubviews或视图控制器中的viewDidLayoutSubviews以便更新图层路径,但是坦率地说,这比看起来如此琐碎的事情要花更多的精力。

检查以下要点。 评论很好,所以应该很容易理解。

更新!

我偶然发现了StackOverflow帖子(当然),找到了可以用来避免添加子视图的替代解决方案。 魔术发生在: shadowLayer.path = UIBezierPath(roundedRect: bounds, cornerRadius: cornerRadius).cgPath

layoutSubviews方法

如果您有其他解决方案或建议,我很想听听他们的意见! 感谢您的阅读,希望对您有所帮助!