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

如何为自定义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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 03:40:09