Другой вид строки в SwiftUI

#swiftui

#swiftui

Вопрос:

У меня есть две строки, и вторая строка должна быть выровнена с первой строкой, за исключением последнего элемента. Вот графическое представление…

Чего я хочу:

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

Вот мой код:

 struct TwoRowView: View {
    
    var body: some View {
        VStack {
            HStack {
                ForEach(0..<6) { i in
                    Text("(i)")
                        .padding(.vertical, 10)
                        .frame(maxWidth: .infinity)
                        .background(Color.red)
                }
            }.padding(.bottom, 5)
            
            HStack {
                ForEach(6..<10) { i in
                    Text("(i)")
                        .padding(.vertical, 10)
                        .frame(maxWidth: .infinity)
                        .background(Color.red)
                }
            }
        }.padding()
    }
}
  

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

1.Можете ли вы использовать iOS 14? Если да, пожалуйста, ознакомьтесь LazyVGrid hackingwithswift.com/quick-start/swiftui /…

2. @bonkyfronk Да, брат, я использую iOS 14.

Ответ №1:

Вот один из способов сделать это для этого конкретного экземпляра.

Я работаю, рассматривая вторую строку как HStack с 3 элементами, и эти 3 элемента являются либо другим HStack с 2 элементами, либо одним элементом.

 struct ContentView: View {
    
    var body: some View {
        VStack {
            HStack {
                ForEach(0..<6) { i in
                    Text("(i)")
                        .padding(.vertical, 10)
                        .frame(maxWidth: .infinity)
                        .background(Color.red)
                }
            }.padding(.bottom, 5)
            
            HStack {
                ForEach(6..<11) { i in
                    if i.isMultiple(of: 2) {
                        HStack {
                            ForEach(0..<(i == 10 ? 1 : 2)) { j in
                            Text("(i   j)")
                                .padding(.vertical, 10)
                                .frame(maxWidth: .infinity)
                                .background(Color.red)
                            }
                        }
                    }
                }
            }
        }.padding()
    }
}
  

Ответ №2:

Здесь возможен подход с динамическим определением ширины базового элемента (также введены некоторые константы для уменьшения жесткого кодирования)

Демо подготовлено и протестировано с Xcode 12 / iOS 14

демо1

demo2

 struct TwoRowView: View {
    let last1 = 5 // 7
    let last2 = 9 // 12
    @State private var baseWidth = CGFloat.zero

    var body: some View {
        VStack {
            HStack {
                ForEach(0..<last1 1) { i in
                    Text("(i)")
                        .padding(.vertical, 10)
                        .frame(maxWidth: .infinity)
                        .background(GeometryReader {
                                if i == last1 {
                                  // read dynamic width once by last item
                                    Color.red
                                        .preference(key: ViewWidthKey.self, value: $0.frame(in: .local).size.width)
                                } else {
                                    Color.red
                                }
                            })

                }
            }.padding(.bottom, 5)
            .onPreferenceChange(ViewWidthKey.self) {
                self.baseWidth = $0
            }

            HStack {
                ForEach(6..<last2 1) { i in
                    Text("(i)")
                        .padding(.vertical, 10)
                        .frame(maxWidth: i == last2 ? .infinity : self.baseWidth )
                        .background(Color.red)
                }
            }
        }.padding()
    }
}

struct ViewWidthKey: PreferenceKey {
    typealias Value = CGFloat
    static var defaultValue = CGFloat.zero
    static func reduce(value: inout Value, nextValue: () -> Value) {
        value  = nextValue()
    }
}