如何为自定义SwiftUI菱形Shape添加圆角?
为SwiftUI自定义菱形Shape添加圆角的实现方案
方案一:手动绘制带圆角的路径
这种方法通过在菱形的每个转角处替换为圆弧,能精准控制圆角效果,避免系统默认修饰符的异常表现。
struct DiamondShape: Shape { var cornerRadius: CGFloat = 8 func path(in rect: CGRect) -> Path { var path = Path() let center = CGPoint(x: rect.width / 2, y: rect.height / 2) // 计算当前菱形允许的最大圆角半径,防止圆角过大导致路径变形 let maxAllowedRadius = min(rect.width, rect.height) / 2 let safeRadius = min(cornerRadius, maxAllowedRadius) // 定义各段直线的端点(避开圆角区域) let topSegmentEnd = CGPoint(x: center.x, y: safeRadius) let rightSegmentStart = CGPoint(x: rect.width - safeRadius, y: center.y) let rightSegmentEnd = CGPoint(x: rect.width, y: center.y + safeRadius) let bottomSegmentStart = CGPoint(x: center.x + safeRadius, y: rect.height) let bottomSegmentEnd = CGPoint(x: center.x, y: rect.height - safeRadius) let leftSegmentStart = CGPoint(x: safeRadius, y: center.y) let leftSegmentEnd = CGPoint(x: 0, y: center.y - safeRadius) let topSegmentStart = CGPoint(x: center.x - safeRadius, y: 0) path.move(to: topSegmentEnd) // 顶部圆角:连接顶部中点到右侧直线起点 path.addArc( tangent1End: CGPoint(x: center.x, y: 0), tangent2End: rightSegmentStart, radius: safeRadius ) path.addLine(to: rightSegmentEnd) // 右侧圆角:连接右侧中点到底部直线起点 path.addArc( tangent1End: CGPoint(x: rect.width, y: center.y), tangent2End: bottomSegmentStart, radius: safeRadius ) path.addLine(to: bottomSegmentEnd) // 底部圆角:连接底部中点到左侧直线起点 path.addArc( tangent1End: CGPoint(x: center.x, y: rect.height), tangent2End: leftSegmentStart, radius: safeRadius ) path.addLine(to: leftSegmentEnd) // 左侧圆角:连接左侧中点到顶部直线起点 path.addArc( tangent1End: CGPoint(x: 0, y: center.y), tangent2End: topSegmentStart, radius: safeRadius ) path.addLine(to: topSegmentEnd) return path } }
方案二:使用Path的rounded方法简化实现
利用系统提供的rounded(_:cornerRadius:)方法,直接对原始菱形路径添加圆角,代码更简洁,但需要注意圆角半径的限制。
struct DiamondShape: Shape { var cornerRadius: CGFloat = 8 func path(in rect: CGRect) -> Path { var path = Path() let center = CGPoint(x: rect.width / 2, y: rect.height / 2) // 绘制原始菱形路径 path.move(to: CGPoint(x: center.x, y: 0)) path.addLine(to: CGPoint(x: rect.width, y: center.y)) path.addLine(to: CGPoint(x: center.x, y: rect.height)) path.addLine(to: CGPoint(x: 0, y: center.y)) path.closeSubpath() // 给路径添加圆角,.continuous保证圆角过渡自然 let maxAllowedRadius = min(rect.width, rect.height) / 2 return path.rounded(.continuous, cornerRadius: min(cornerRadius, maxAllowedRadius)) } }
使用示例
两种方案都可以直接在View中调用:
struct ContentView: View { var body: some View { DiamondShape(cornerRadius: 12) .fill(Color.blue) .frame(width: 200, height: 200) } }
注:两种方案都加入了圆角半径的安全限制,避免因设置过大的radius导致路径变形。
内容的提问来源于stack exchange,提问作者John B
相关产品推荐
相关产品推荐

