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
相关产品推荐
相关产品推荐

