You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI中实现带内嵌效果的重复自定义形状绘制

实现SwiftUI自定义内嵌多层描边三角形

你已经实现了基础的自定义三角形描边,要添加多层内嵌的不同样式描边,确实需要让自定义形状遵循InsettableShape协议,配合strokeBorder使用。以下是具体实现步骤:

1. 修改自定义形状,遵循InsettableShape协议

给CustomShape添加内嵌偏移支持,通过存储偏移量,绘制路径时基于偏移后的矩形生成新路径:

struct CustomShape: InsettableShape {
    // 存储内嵌偏移量,默认值为0
    @usableFromInline var insetAmount: CGFloat = 0
    
    // 实现InsettableShape协议方法,返回偏移后的新形状
    func inset(by amount: CGFloat) -> Self {
        var shape = self
        shape.insetAmount += amount
        return shape
    }
    
    func path(in rect: CGRect) -> Path {
        // 计算内嵌后的矩形范围
        let insetRect = rect.insetBy(dx: insetAmount, dy: insetAmount)
        var path = Path()
        path.move(to: CGPoint(x: insetRect.minX, y: insetRect.minY))
        path.addLine(to: CGPoint(x: insetRect.maxX, y: insetRect.minY))
        path.addLine(to: CGPoint(x: insetRect.midX, y: insetRect.maxY))
        path.closeSubpath()
        return path
    }
}

2. 在视图中叠加多层strokeBorder

通过多次调用strokeBorder,指定不同颜色和线宽,实现多层内嵌描边效果:

struct ContentView: View {    
    var body: some View {
        ZStack {
            CustomShape()
                // 最外层蓝色描边,线宽5
                .strokeBorder(Color.blue, lineWidth: 5)
                // 第一层内嵌红色描边,线宽4
                .strokeBorder(Color.red, lineWidth: 4)
                // 第二层内嵌绿色描边,线宽3
                .strokeBorder(Color.green, lineWidth: 3)
                .frame(width: 300, height: 200)
        }
        .ignoresSafeArea()
    }
}

原理说明

  • InsettableShape协议的核心是inset(by:)方法,每次调用strokeBorder时,SwiftUI会自动根据线宽计算内嵌偏移量,调用该方法生成偏移后的新路径。
  • strokeBorder与stroke的区别在于:strokeBorder将描边绘制在形状内部,不会超出原形状边界;而stroke是居中绘制,会有一半线宽溢出形状范围。多层叠加时,每层描边会向内收缩,不会互相重叠溢出。

内容的提问来源于stack exchange,提问作者batman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 15:25:09