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

SwiftUI中如何从Path.Element组件正确重建Path?

SwiftUI中如何从Path.Element组件正确重建Path?

我明白你现在遇到的问题了——把Path拆成Element组件后重新拼接,控制台总是弹出CGPathAddCurveToPoint: no current point这类错误,明明没修改任何坐标值,却就是画不对,确实挺闹心的。

咱们来看看问题出在哪:你的pathComponents函数里,处理.move(to:)元素的顺序有问题!

原来的代码里,你先把当前元素加入currentElements,再判断是否要保存之前的路径。这就导致当遇到新的move时,这个move元素会被错误地包含到上一个子路径的pathElements里,而新的子路径的pathElements反而丢失了开头的move指令。后续重建Path时,没有move来设置起始点,直接执行line、curve这些指令,自然就会报“没有当前点”的错误。

修复方案

调整pathComponents函数里的逻辑,把currentElements.append(element)的操作放到每个case的内部,确保每个元素都被正确归属到对应的子路径中:

func pathComponents(path: Path) -> [CustomPath] {
    
    var components: [CustomPath] = []
    var currentPath = Path()
    var currentElements: [Path.Element] = []
    
    path.forEach { element in
        
        switch element {
        case .move(to: let point):
            // 先保存之前的子路径(如果存在)
            if !currentPath.isEmpty {
                components.append(CustomPath(pathValue: currentPath, pathElements: currentElements))
                currentPath = Path()
                currentElements = []
            }
            // 再把当前move元素加入新的子路径元素列表
            currentElements.append(element)
            currentPath.move(to: point)
            
        case .line(to: let point):
            currentElements.append(element)
            currentPath.addLine(to: point)
            
        case .quadCurve(to: let endPoint, control: let controlPoint):
            currentElements.append(element)
            currentPath.addQuadCurve(to: endPoint, control: controlPoint)
            
        case .curve(to: let endPoint, control1: let control1, control2: let control2):
            currentElements.append(element)
            currentPath.addCurve(to: endPoint, control1: control1, control2: control2)
            
        case .closeSubpath:
            currentElements.append(element)
            currentPath.closeSubpath()
            components.append(CustomPath(pathValue: currentPath, pathElements: currentElements))
            currentPath = Path()
            currentElements = []
        }
    }
    
    // 处理最后一个未闭合的子路径
    if !currentPath.isEmpty {
        components.append(CustomPath(pathValue: currentPath, pathElements: currentElements))
    }
    
    return components
}

另外,你的第二个GeometryReader里的布局代码有点小问题——多个View没有用容器包裹,建议用ZStack把背景色和所有路径包起来,这样红色路径才能正确叠加在白色背景上:

GeometryReader { proxy in
    ZStack {
        Color.white
        ForEach(myCustomPathComponents) { item in
            myFunc(value: item.pathElements)
                .stroke(Color.red, lineWidth: 2.0)
        }
    }
}

这样修改之后,每个子路径的pathElements都会以正确的move指令开头,重建Path时就不会出现“没有当前点”的错误,红色路径也能和黑色路径完美重叠啦。

备注:内容来源于stack exchange,提问作者swiftPunk

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.15 08:50:28