SwiftUI - 将两个不同的路径合并为一个或更改 strokeStyle 中间绘图

SwiftUI - Merge two different Paths into one OR change strokeStyle mid-drawing

我有一个用线连接的垂直点列表。直到所谓的“活动点”,线条应该是实线,并且从活动点开始是虚线(隐喻用户已经完成的事情和即将发生的事情)。

这是它在 Android 上的样子:

最后是一条很长的路,只是中间换了个风格。如何将这两者合二为一?

我在想象这样的事情:

func drawPaths(points: [CGPoint]) -> some Shape {
        let activeChlgIndex = (chlgViewModel.activeChallenge?.id ?? -1)
        var wholePath: Path
        
        // Before active challenge
        var solidPath =  Path { path in
            path.move(to: points[0])
            
            for (i, _) in points.enumerated() {
                if (i <= activeChlgIndex) {
                    path.addLine(to: points[i])
                }
            }
        }
        .stroke(lineWidth: 2)
        .foregroundColor(.pathColorSolid)
        
        // After active challenge
        var dottedPath =  Path { path in
            path.move(to: points[activeChlgIndex])
            
            for (i, _) in points.enumerated() {
                if (i >= activeChlgIndex) {
                    path.addLine(to: points[i])
                }
            }
        }
        .stroke(style: StrokeStyle(lineWidth: 2, dash: [5]))
        .foregroundColor(.pathColorDotted)
        
        wholePath = solidPath.addPath(dottedPath)
        
        return wholePath
    }

最后让它们成为两条独立的路径是最简单的解决方案。

颜色只能在 body 函数的 return 之后应用,否则它是一些 ColoredView<XYZ> 左右并且不能 returned 为 any Shape

    var body: some View {
        ScrollView {
            GeometryReader { geometry in
                let points = calculatePoints(geometry: geometry)
                let activeChlgIndex = (chlgViewModel.activeChallenge?.id ?? -1) - 1
                drawSolidPaths(points: points, activeChlgIndex: activeChlgIndex)
                    .foregroundColor(.pathColorSolid)
                drawDottedPaths(points: points, activeChlgIndex: activeChlgIndex)
                    .foregroundColor(.pathColorDotted)
                drawCircles(geometry: geometry, points: points, activeChlgIndex: activeChlgIndex)
            }
        }
    }
    
    func drawSolidPaths(points: [CGPoint], activeChlgIndex: Int) -> some Shape {
        let pointsUpToActiveChlg = Array(points[0 ... activeChlgIndex])
        
        return Path { path in
            path.move(to: pointsUpToActiveChlg[0])
            
            for (i, _) in pointsUpToActiveChlg.enumerated() {
                path.addLine(to: pointsUpToActiveChlg[i])
            }
        }
        .stroke(lineWidth: 2)
    }
    
    func drawDottedPaths(points: [CGPoint], activeChlgIndex: Int) -> some Shape {
        let pointsFromActiveChlg = Array(points[activeChlgIndex ..< points.count])
        
        return Path { path in
            path.move(to: pointsFromActiveChlg[0])
            
            for (i, _) in pointsFromActiveChlg.enumerated() {
                path.addLine(to: pointsFromActiveChlg[i])
            }
        }
        .stroke(style: StrokeStyle(lineWidth: 2, dash: [5]))
    }