Сетка SwiftUI со столбцом, подходящим для содержимого?
Возможен ли такой макет с SwiftUI?
Я хочу, чтобы в первом столбце был заключен размер меток, поэтому в этом случае он будет достаточно большим, чтобы отобразить "Bigger Label:". Затем оставшееся место отдайте второму столбцу.
Этот макет довольно прост с автоматическим макетом.
SwiftUI 2020 имеет
LazyVGrid
но единственные способы, которые я вижу для установки размеров столбцов, используют жестко заданные числа. Разве они не понимают, в чем проблема с несколькими языками и настраиваемыми пользователем размерами шрифтов?
1 ответ
Это не так сложно, если сравнить количество строк кода, чтобы сделать это программно в обоих мирах...
Во всяком случае, конечно, это возможно. Вот решение, основанное на некотором модификаторе справки с использованием функции предпочтений просмотра. Нетрудно. Нет сетки.
Демо подготовлено и протестировано с Xcode 12 / iOS 14.
struct DemoView: View {
@State private var width = CGFloat.zero
var body: some View {
VStack {
HStack {
Text("Label1")
.alignedView(width: $width)
TextField("", text: .constant("")).border(Color.black)
}
HStack {
Text("Bigger Label")
.alignedView(width: $width)
TextField("", text: .constant("")).border(Color.black)
}
}
}
}
и помощники
extension View {
func alignedView(width: Binding<CGFloat>) -> some View {
self.modifier(AlignedWidthView(width: width))
}
}
struct AlignedWidthView: ViewModifier {
@Binding var width: CGFloat
func body(content: Content) -> some View {
content
.background(GeometryReader {
Color.clear
.preference(key: ViewWidthKey.self, value: $0.frame(in: .local).size.width)
})
.onPreferenceChange(ViewWidthKey.self) {
if $0 > self.width {
self.width = $0
}
}
.frame(minWidth: width, alignment: .trailing)
}
}