Как создать иерархический вид с вложенными дочерними представлениями в SwiftUI

Вопрос или проблема

Как создать иерархический вид с вложенными дочерними представлениями в SwiftUI

Как сделать это с помощью SwiftUI

Я пытался сделать этот дизайн на SwiftUI, и он выглядит похоже, но я не думаю, что этот подход является более чистым. Я прикрепляю свой код ниже.

struct NewShapeView: View {

let properties: [Property]

var body: some View {
    ForEach(properties) { property in
        VStack(alignment: .leading, spacing: 0) {
            ForEach(property.zones.indices, id: \.self) { index in
                LineView(zoneName: property.zones[index].name)
                SubView(showVerticalLine: index != property.zones.indices.last)
                    
            }
        }
    }
}

}

struct LineView: View {

let zoneName: String

var body: some View {
    HStack(alignment: .bottom, spacing: 0) {
        Rectangle().frame(width: 1, height: 40)
        Rectangle().frame(width: 40, height: 1)
        Text(zoneName)
    }
}

}

struct SubView: View {

var showVerticalLine: Bool

var body: some View {
    HStack(spacing: 0) {
        if showVerticalLine {
            Rectangle().frame(width: 1, height: 40) // Протяните линию через SubView
        }
        Spacer().frame(width:  32, height: 36) // Настройте ширину спейса для выравнивания с предыдущей линией
        Image(systemName: "speaker.wave.2.fill")
        Text("Некоторый Парадиз - L’impératrice")
            .font(.subheadline)
            .foregroundColor(.gray)
    }
}

}

Я новичок и работаю над своим первым производственным приложением на SwiftUI. Любые предложения и помощь приветствуются. Спасибо заранее.

Я пытался сделать хак, рисуя вертикальную линию на границе подвидов зоны до тех пор, пока не будет найден последний вид в массиве. Я ожидаю более чистый подход.

Ответ или решение

Для создания иерархического представления с вложенными дочерними представлениями в SwiftUI можно использовать несколько улучшений по сравнению с вашим текущим кодом. Я предложу более чистый и структурированный подход, используя SwiftUI, чтобы создать представление, похожее на то, что вы прикрепили. Мы сделаем ваш код более удобочитаемым и организованным, сохраняя его функциональность.

import SwiftUI

struct Property: Identifiable {
    let id: UUID
    let zones: [Zone]
}

struct Zone: Identifiable {
    let id: UUID
    let name: String
}

struct NewShapeView: View {
    let properties: [Property]

    var body: some View {
        ScrollView {
            ForEach(properties) { property in
                VStack(alignment: .leading, spacing: 20) {
                    Text("Property \(property.id.uuidString.prefix(5))")
                        .font(.headline)

                    ForEach(property.zones.indices, id: \.self) { index in
                        ZoneView(zone: property.zones[index], showVerticalLine: index < property.zones.count - 1)
                    }
                }
                .padding()
            }
        }
    }
}

struct ZoneView: View {
    let zone: Zone
    var showVerticalLine: Bool

    var body: some View {
        HStack(spacing: 0) {
            VStack(spacing: 0) {
                if showVerticalLine {
                    Rectangle()
                        .frame(width: 1, height: 40)
                        .foregroundColor(.gray)
                }
                Rectangle()
                    .frame(width: 40, height: 1)
                    .foregroundColor(.gray)
            }
            Text(zone.name)
                .padding(.leading, 10)
                .font(.body)
        }
    }
}

struct ContentView: View {
    let properties = [
        Property(id: UUID(), zones: [
            Zone(id: UUID(), name: "Zone 1"),
            Zone(id: UUID(), name: "Zone 2"),
            Zone(id: UUID(), name: "Zone 3")
        ]),
        Property(id: UUID(), zones: [
            Zone(id: UUID(), name: "Zone A"),
            Zone(id: UUID(), name: "Zone B")
        ])
    ]

    var body: some View {
        NewShapeView(properties: properties)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

Пояснения к коду:

  1. Модели данных: Мы создали две структуры Property и Zone, которые реализуют протокол Identifiable. Это поможет SwiftUI правильно отслеживать и идентифицировать элементы в списке.

  2. Основное представление (NewShapeView): Мы используем ScrollView для прокрутки списка свойств. Каждый объект Property выводится с заголовком и связанными с ним зонами.

  3. Представление зоны (ZoneView): Это представление обрабатывает вывод имени зоны и условное отображение вертикальной линии, если текущая зона не последняя. Мы используем VStack для организации вертикального отображения.

  4. Проверка условий: Вместо того, чтобы использовать индексы в ForEach, я проверяю, является ли текущая зона предпоследней (используя index < property.zones.count - 1), чтобы отобразить вертикальную линию только если это необходимо.

  5. Предпросмотр (ContentView_Previews): Используется для предварительного просмотра вашего интерфейса в Xcode.

Этот код более организован и читабелен, и он позволяет расширить функциональность в дальнейшем без значительных изменений.

Оцените материал
Добавить комментарий

Капча загружается...