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

SwiftUI绘制无弦圆弧异常:如何复刻目标SVG图形?

SwiftUI复刻SVG圆弧路径问题解决

我需要在SwiftUI中复刻以下SVG定义的图形:

<svg
   width="256"
   height="256"
   viewBox="0 0 256 256"
   version="1.1"
   xmlns:svg="http://www.w3.org/2000/svg">
  <path
     id="path4"
     style="font-size:12px;fill:#000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.01mm;stroke-linecap:round"
     d="M 0.00 0 A 128 128 0.00 0 0 128 128 L 0 128 Z" />
</svg>

该图形是从(0,0)出发的圆弧连接到(128,128),再连线至(0,128)后闭合的形状。

我编写了如下SwiftUI代码尝试实现,但生成的图形异常:SwiftUI自动绘制了圆弧的弦,且path.addLine(to: CGPoint(x: 0, y: 128))语句完全被忽略:

import SwiftUI

struct ArcPath: Shape {
    func path(in rect: CGRect) -> Path {
        var path = Path()
        path.move(to: CGPoint(x: 0, y: 0))
        let startPoint = path.currentPoint!
        let to = CGPoint(x: 128, y: 128)
        let radius = 128.0
        let center = CGPoint(x: 128, y: 0)
        let angle1 = Angle(degrees: 90)
        let angle2 = Angle(degrees: 180)
        path.addArc(center: center, radius: radius, startAngle: angle1, endAngle: angle2, clockwise: false)
        path.addLine(to: CGPoint(x: 0, y: 128))
        path.closeSubpath()
        return path
    }
}

struct ContentView: View {
    var body: some View {
        VStack {
            ArcPath()
                .fill(.black)
        }
        .frame(width: 256, height: 256)
        .padding()
    }
}

问题原因

  • addArc的自动连线行为:SwiftUI的addArc方法会自动将当前路径的最后一个点与圆弧的起始点用直线连接。你的代码中,move(to: (0,0))后,圆弧的起始点是(128,128)(对应angle1 = 90°),所以系统自动添加了一条从(0,0)到(128,128)的直线,也就是你看到的"弦"。
  • 圆弧起止角度颠倒:你设置的startAngle=90°、endAngle=180°,导致圆弧的绘制方向和终点完全错误,后续的addLine被错误的路径覆盖,看起来像是被忽略。

修复后的代码

import SwiftUI

struct ArcPath: Shape {
    func path(in rect: CGRect) -> Path {
        var path = Path()
        let radius = 128.0
        let center = CGPoint(x: 128, y: 0)
        // 从(0,0)出发,对应圆心(128,0)的180°方向
        let startAngle = Angle(degrees: 180)
        // 到(128,128),对应圆心(128,0)的90°方向
        let endAngle = Angle(degrees: 90)
        
        // 直接添加圆弧,路径为空时会自动moveTo圆弧起点(0,0)
        path.addArc(center: center, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: false)
        // 从圆弧终点(128,128)连线到(0,128)
        path.addLine(to: CGPoint(x: 0, y: 128))
        // 闭合路径,从(0,128)回到起点(0,0)
        path.closeSubpath()
        
        return path
    }
}

struct ContentView: View {
    var body: some View {
        VStack {
            ArcPath()
                .fill(.black)
        }
        .frame(width: 256, height: 256)
        .padding()
    }
}

关键说明

  • 调整圆弧的startAngle和endAngle,使其对应正确的起点(0,0)和终点(128,128):
    • (0,0)相对于圆心(128,0)在左侧,对应角度180°
    • (128,128)相对于圆心(128,0)在正下方,对应角度90°
  • 设置clockwise: false,对应SVG路径中的sweep-flag: 0(逆时针绘制)
  • 不需要提前move(to: (0,0)),因为addArc在路径为空时会自动将起点设置为圆弧的起始点,避免了不必要的自动连线

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 06:50:05