在创建自定义 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 应用到圆角矩形上,我们想要的镂空图形就成了。