在创建自定义 UI 的时候,View 常常会是非矩形的窗口,最常见的就是圆角矩形了。还有一种情况是不规则的图形,比如缺了某个角,或中间镂个空。在 SwiftUI 下做这个,可以说是非常方便的。
假如我们在要在一个矩形里镂一个圆形,只需要这么做:
import SwiftUI func HoleShapeMask(in rect: CGRect) -> some View { var shape = Rectangle().path(in: rect) shape.addPath(Circle().path(in: rect)) return shape.fill(style: FillStyle(eoFill: true)) } struct ContentView: View { var body: some View { GeometryReader(content: { geometry in RoundedRectangle(cornerRadius: 10) .fill(Color.blue) .mask(HoleShapeMask(in: CGRect(origin: .zero, size: geometry.size))) }) } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() .frame(width: 300, height: 300, alignment: .center) } }
结果如下:
代码解读
重点是在 HoleShapeMask 这个方法里,由于 SwiftUI 代码很简练,三行就搞定了。这三行的意思是:
- 先在 rect 大小里做一个矩形;
- 再在这个矩形里加一个圆形;
- 矩形+圆形的填充方式,使用 eoFill 的形式进行;
什么是 eoFill 呢?就是奇偶(even-odd)填充法。相当于给 CAShapeLayer
的 fillRule
属性设置了 evenOdd
方法。
最后把这个 Shape(Path)作为 Mask 应用到圆角矩形上,我们想要的镂空图形就成了。