У меня есть простой список, и я хочу контролировать высоту строки.
Цели:
- Минимальная высота строки должна быть высотой из первых двух элементов в VStack.
- Максимальная высота строки должна быть не меньше минимальной высоты или высоты высоты элемента одного из других элементов Text.
- Другой текстовые элементы могут быть многострочными.
Это, см. код, это то, что я получил до сих пор. Ширина работает, но не вместе с высотой. Высота слишком велика. Занят часами с этим. Добавлена информация - я хочу, чтобы для всех элементов была высота «один» и для всех строк, чтобы все строки имели только одну и ту же высоту. Высота должна соответствовать высоте элемента высоты в строке (я вычисляю VStack как один элемент). Ширина на данный момент важна только для первого VStack в строке.
Как правильно это понять?
Второй вопрос: Отрицательный отступ как Padding (-6) разрешено? Или есть альтернатива?
Границы предназначены для отладки и должны работать под macOS.
Есть мысли по этому поводу?
Конечно, спасибо.
import SwiftUI
struct windowSize {
let minWidth : CGFloat = 300
let minHeight : CGFloat = 300
let maxWidth : CGFloat = 600
let maxHeight : CGFloat = 650
}
struct WidthPreferenceKey: PreferenceKey {
typealias Value = CGFloat
static var defaultValue: CGFloat = 0
static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {
value = nextValue()
}
}
struct HeightPreferenceKey: PreferenceKey {
typealias Value = CGFloat
static var defaultValue: CGFloat = 0
static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {
value = nextValue()
}
}
struct ListItemGeometry: View {
var body: some View {
GeometryReader { geometryListItem in
Rectangle()
.fill(Color.clear)
.preference(key: WidthPreferenceKey.self, value: geometryListItem.size.width)
.preference(key: HeightPreferenceKey.self, value: geometryListItem.size.height)
}
.scaledToFill()
}
}
struct myData : Identifiable {
let id = UUID()
var dayNumber : Int
var dayName : String
var title : String
var action : String
}
struct ContentView : View {
@State var maxDateLabelWidth: CGFloat = 0
@State var maxLabelHeight: CGFloat = 0
private let myDataArray : [myData] = [myData(dayNumber: 1, dayName: "Ma",title: "Title, which is quit long",action: "Nothing"),
myData(dayNumber: 2, dayName: "Di",title: "Title, which is quit long, which is quit long",action: "Nothing"),
myData(dayNumber: 3, dayName: "Wo",title: "Title, which is quit long, which is quit longwhich is quit long",action: "Nothing"),
myData(dayNumber: 4, dayName: "Do",title: "Title, which is not so long",action: "Nothing"),
myData(dayNumber: 12, dayName: "Vr",title: "Title, which is quit long",action: "Nothing"),
myData(dayNumber: 30, dayName: "Woe",title: "Title, which is quit longwhich is quit longwhich is quit long",action: "Nothing - which is quit long which is quit long")]
var body: some View {
Group(){
HStack{
Spacer(minLength: 50)
//ScrollView(.horizontal, showsIndicators: true){
List(myDataArray) { item in
ListItem( maxDateLabelWidth : self.$maxDateLabelWidth,
maxLabelHeight : self.$maxLabelHeight,
data : item)
.border(Color.red, width: 1)
}
//}.padding(.horizontal)
}
.border(Color.green, width: 1)
.frame(minWidth: windowSize().minWidth, minHeight: windowSize().minHeight)
.frame(maxWidth: windowSize().maxWidth, maxHeight: windowSize().maxHeight)
}
}
}
struct ListItem : View {
@Binding var maxDateLabelWidth: CGFloat
@Binding var maxLabelHeight: CGFloat
let data: myData
var body: some View {
HStack {
VStack(alignment: .center) {
Text("\(data.dayNumber)")
.frame(alignment: .center)
.border(Color.blue, width: 1)
.font(.caption)
Text(data.dayName)
.border(Color.yellow, width: 1)
.font(.body)
}
.border(Color.gray, width: 1)
.frame(width: self.maxDateLabelWidth - 60)
.background(ListItemGeometry())
.onPreferenceChange(WidthPreferenceKey.self) {
if $0 > self.maxDateLabelWidth {
self.maxDateLabelWidth = $0
}
}
// ----------------
Divider().padding(-6) // -6 allowed??? Alternative?
// ----------------
Text(data.title)
.frame(width: 160, alignment: .leading)
.frame( height: self.maxLabelHeight)
.background(ListItemGeometry())
.onPreferenceChange(HeightPreferenceKey.self) {
if $0 > self.maxLabelHeight {
self.maxLabelHeight = $0
}
}
.border(Color.blue, width: 1)
.lineLimit(3)
// ----------------
Divider().padding(0)
// ----------------
Text(data.action)
.frame(width: 160, alignment: .leading)
.frame(height: self.maxLabelHeight)
.background(ListItemGeometry())
.onPreferenceChange(HeightPreferenceKey.self) {
if $0 > self.maxLabelHeight {
self.maxLabelHeight = $0
}
}
.border(Color.blue, width: 1)
.lineLimit(3)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Спасибо за чтение.