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

