macOS Swiftui List и Geometry - высота и ширина строки под контролем - PullRequest
0 голосов
/ 18 апреля 2020

У меня есть простой список, и я хочу контролировать высоту строки.

Цели:

  • Минимальная высота строки должна быть высотой из первых двух элементов в 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()
    }
}

Спасибо за чтение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...