SwiftUI:如何通过 Mask 做不规则图形

在创建自定义 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)
    }
}

结果如下:

SwiftUI Shape Mask.png

代码解读

重点是在 HoleShapeMask 这个方法里,由于 SwiftUI 代码很简练,三行就搞定了。这三行的意思是:

  • 先在 rect 大小里做一个矩形;
  • 再在这个矩形里加一个圆形;
  • 矩形+圆形的填充方式,使用 eoFill 的形式进行;

什么是 eoFill 呢?就是奇偶(even-odd)填充法。相当于给 CAShapeLayerfillRule 属性设置了 evenOdd 方法。

最后把这个 Shape(Path)作为 Mask 应用到圆角矩形上,我们想要的镂空图形就成了。

参考资料

欢迎使用图拉鼎和他的团队开发的作品

One Switch - 多功能开关工具

常驻 macOS 菜单栏的开关工具,可以快速开关 AirPods、睡眠模式、切换黑暗模式等。

No Comment

Leave a Comment