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]))
}
我有一个用线连接的垂直点列表。直到所谓的“活动点”,线条应该是实线,并且从活动点开始是虚线(隐喻用户已经完成的事情和即将发生的事情)。
这是它在 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]))
}