iOS常用OC-开发案例收集很常

iOS 切带阴影的圆角

2021-03-16  本文已影响0人  天外丶飞仙

在项目中遇到了一个这种需求的式样

6sD7pd.png

如图所示一个矩形四个角有一定弧度的圆角,矩形中间有两个向内切的半圆,矩形的最外层是带阴影效果的且阴影会根据圆角进行切割.

拿到这个需求最简单的方案让 UI 切一个带有阴影的背景图,我们直接使用图片来完成。但是在实际需求中间半圆的位置是不固定的。无法确定拉伸的部分。所以还是选择代码实现。

矩形四个圆角和阴影

实现矩形的四个圆角很简单,也是我们通常会用的方法。

bgView.layer.cornerRadius = 10
bgView.layer.masksToBounds = true

上面两行代码就可以搞定圆角,但是你再给 bgView 设置阴影是没有效果的。因为阴影是在视图外部完成的效果,并且masksToBounds 设置为 YES 会告诉 UIView 不要绘制自身外部的所有内容。

解决方式就是在 bgView 的下面在添加一个 frame 一样的 shadowView 专门用来画阴影。

shadowView.layer.shadowOpacity = 1
shadowView.layer.shadowRadius = 10
shadowView.layer.shadowColor = UIColor.darkGray.cgColor
shadowView.layer.shadowOffset = CGSize(width: 10, height: 10)
shadowView.backgroundColor = .clear

这里需要注意的地方是 shadowView 的背景色设置为透明,不然四个切圆角的地方就会漏出来。但是改成透明色后你会发现阴影效果没有了。因为只有当 View 不透明或其中包含某些内容时才会出现阴影。

解决方式是设置 shadowPath 属性。

let path0 = UIBezierPath(roundedRect: shadowView.bounds, byRoundingCorners: .allCorners, cornerRadii: CGSize(width: 10, height: 10))
shadowView.layer.shadowPath = path0.cgPath

这样我们就可以画出带四个圆角和阴影效果的矩形了。

6sw7pn.png

中间的半圆和阴影

要实现两个内切的半圆,我们可以使用 CALayer 的 mask 属性来实现。

图层蒙板mask

这个属性本身就是个 CALayer 类型,有和其他图层一样的绘制和布局属性。它类似于一个子图层,mask 图层定义了父图层的部分可见区域。只需要定义好 mask 图层的轮廓,mask 图层实心的部分会被保留下来,其他的则会被抛弃。

我们给 bgView layer 设置 mask。用 UIBezierPath 来描绘 mask 的轮廓。

let path = UIBezierPath(rect: bgView.bounds)
path.append(UIBezierPath(arcCenter: CGPoint(x: 0, y: bgView.bounds.height * 0.5), radius: 10, startAngle: CGFloat(Double.pi / 2) , endAngle: CGFloat(Double.pi * 3 / 2), clockwise: false))
path.append(UIBezierPath(arcCenter: CGPoint(x: bgView.bounds.width, y: bgView.bounds.height * 0.5), radius: 10, startAngle: CGFloat(Double.pi * 3 / 2), endAngle: CGFloat(Double.pi / 2), clockwise: false))
let shape = CAShapeLayer()
shape.path = path.cgPath
bgView.layer.mask = shape

6s0dcq.png

这样我们就切出来了中间的半圆了。最后我们在对阴影部分按照半圆弧度设置一下 shadowPath。就能得到最终效果了。

let leftCirclePath = UIBezierPath(arcCenter: CGPoint(x: 0, y: bgView.bounds.height * 0.5), radius: 10, startAngle: CGFloat(Double.pi / 2) , endAngle: CGFloat(Double.pi * 3 / 2), clockwise: false)
let rightCirclePath = UIBezierPath(arcCenter: CGPoint(x: bgView.bounds.width, y: bgView.bounds.height * 0.5), radius: 10, startAngle: CGFloat(Double.pi * 3 / 2), endAngle: CGFloat(Double.pi / 2), clockwise: false)
let shadowPath = UIBezierPath(roundedRect: shadowView.bounds, byRoundingCorners: .allCorners, cornerRadii: CGSize(width: 10, height: 10))
shadowPath.append(leftCirclePath)
shadowPath.append(rightCirclePath)
shadowView.layer.shadowPath = shadowPath.cgPath

let maskPath = UIBezierPath(rect: bgView.bounds)
maskPath.append(leftCirclePath)
maskPath.append(rightCirclePath)
let shape = CAShapeLayer()
shape.path = maskPath.cgPath
bgView.layer.mask = shape

6sD7pd.png
上一篇下一篇

猜你喜欢

热点阅读