one of the easiest ways to achieve what you want is to draw a Rectangle below your Circles as the connecting line using a ZStack. like this:
struct ConnectedCircles: View {
var body: some View {
ZStack {
Rectangle()
.fill(Color.blue)
.frame(width: 2, height: 100)
VStack {
Circle()
.strokeBorder(Color.blue,lineWidth: 4)
.background(Circle().foregroundColor(Color(.systemBackground)))
.frame(width: 30, height: 30)
Circle()
.strokeBorder(Color.blue,lineWidth: 4)
.background(Circle().foregroundColor(Color(.systemBackground)))
.frame(width: 30, height: 30)
Circle()
.strokeBorder(Color.blue,lineWidth: 4)
.background(Circle().foregroundColor(Color(.systemBackground)))
.frame(width: 30, height: 30)
}
}
}
}
another solution is creating a custom Shape as our line.:
struct VerticalLine: Shape {
func path(in rect: CGRect) -> Path {
var path = Path()
path.move(to: CGPoint(x: rect.midX, y: rect.minY))
path.addLine(to: CGPoint(x: rect.midX, y: rect.maxY))
return path
}
}
struct ConnectedCircles: View {
var body: some View {
ZStack {
Line()
VerticalLine()
.stroke(Color.blue, lineWidth: 4)
.frame(width: 20, height: 100)
VStack {
Circle()
.strokeBorder(Color.blue,lineWidth: 4)
.background(Circle().foregroundColor(Color(.systemBackground)))
.frame(width: 30, height: 30)
Circle()
.strokeBorder(Color.blue,lineWidth: 4)
.background(Circle().foregroundColor(Color(.systemBackground)))
.frame(width: 30, height: 30)
Circle()
.strokeBorder(Color.blue,lineWidth: 4)
.background(Circle().foregroundColor(Color(.systemBackground)))
.frame(width: 30, height: 30)
}
}
}
}
and you can do it even without using a ZStack. You should set your VStack's spacing to 0 and draw lines between Circles.
struct VerticalLine: Shape {
func path(in rect: CGRect) -> Path {
var path = Path()
path.move(to: CGPoint(x: rect.midX, y: rect.minY))
path.addLine(to: CGPoint(x: rect.midX, y: rect.maxY))
return path
}
}
struct ConnectedCircles: View {
var body: some View {
VStack(spacing: 0) {
Circle()
.strokeBorder(Color.blue,lineWidth: 4)
.frame(width: 30, height: 30)
Line()
VerticalLine()
.stroke(Color.blue, lineWidth: 4)
.frame(width: 20, height: 10)
Circle()
.strokeBorder(Color.blue,lineWidth: 4)
.frame(width: 30, height: 30)
Line()
VerticalLine()
.stroke(Color.blue, lineWidth: 4)
.frame(width: 20, height: 10)
Circle()
.strokeBorder(Color.blue,lineWidth: 4)
.frame(width: 30, height: 30)
}
}
}