Вопрос или проблема
Как создать иерархический вид с вложенными дочерними представлениями в 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()
}
}
Пояснения к коду:
-
Модели данных: Мы создали две структуры
Property
иZone
, которые реализуют протоколIdentifiable
. Это поможет SwiftUI правильно отслеживать и идентифицировать элементы в списке. -
Основное представление (
NewShapeView
): Мы используемScrollView
для прокрутки списка свойств. Каждый объектProperty
выводится с заголовком и связанными с ним зонами. -
Представление зоны (
ZoneView
): Это представление обрабатывает вывод имени зоны и условное отображение вертикальной линии, если текущая зона не последняя. Мы используемVStack
для организации вертикального отображения. -
Проверка условий: Вместо того, чтобы использовать индексы в
ForEach
, я проверяю, является ли текущая зона предпоследней (используяindex < property.zones.count - 1
), чтобы отобразить вертикальную линию только если это необходимо. - Предпросмотр (
ContentView_Previews
): Используется для предварительного просмотра вашего интерфейса в Xcode.
Этот код более организован и читабелен, и он позволяет расширить функциональность в дальнейшем без значительных изменений.