SwiftUI Как соединить объекты линией?

#swiftui

#swiftui

Вопрос:

У меня есть три круга, и я хотел бы нарисовать линии, соединяющие 1<-> 2 и 2<-> 3. Кажется, что формы линии не существует, и даже если бы это было так, как бы я указал соединение. Есть идеи?

Мой текущий код выглядит следующим образом

 struct ConnectedCircles: View {
    var body: some View {
        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)
            
        }
    }
}
  

И создает три несвязанных круга.

введите описание изображения здесь

Хотя я хотел бы создать что-то вроде этого

введите описание изображения здесь

Комментарии:

1. Просто из любопытства — почему вы используете второй круг в качестве фона?

2. @Losiowaty Я просто не хотел, чтобы они были сплошными в принципе

Ответ №1:

один из самых простых способов добиться желаемого — это нарисовать Rectangle под вашими Circle s в качестве соединительной линии с помощью ZStack . вот так:

 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)
                
            }
        }
    }
}
  

другим решением является создание пользовательского Shape типа нашей линии.:

 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)
                
            }
        }
    }
}
  

и вы можете сделать это даже без использования ZStack . Вы должны установить свои VStack ‘s spacing на 0 и рисовать линии между Circle s.

 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)
            
        }
    }
}