SwiftUI - высота списка с изменяемыми размерами, зависящая от количества элементов - PullRequest
0 голосов
/ 23 сентября 2019

У меня проблемы с динамическим изменением высоты списка, зависящей от количества элементов.

Я пробовал это решение, но оно не сработало.

List {
    ForEach(searchService.searchResult, id: \.self) { item in
        Text(item)
        .font(.custom("Avenir Next Regular", size: 12))
    }
}.frame(height: CGFloat(searchService.searchResult.count * 20))

1 Ответ

3 голосов
/ 23 сентября 2019

TL; DR

Дизайнеры SwiftUI не хотят, чтобы вы использовали списки.Либо вам придется придумать хакерское решение, которое, вероятно, сломается в будущем (см. Ниже), либо использовать что-то, кроме списка.

Фон

SwiftUI, как правило, имеет два типа представлений

  1. Те, которые предназначены для легкой модификации и компоновки, обеспечивая неограниченную настраиваемость для уникального внешнего вида.
  2. Те, которые предназначены для обеспечения стандартного, согласованногопочувствуйте какой-то тип взаимодействия, независимо от того, в каком приложении они используются.

Примером типа 1 будет текст.Вы можете изменить размер шрифта, вес, шрифт, цвет, фон, отступы и т. Д. Он предназначен для его изменения.

Примером типа 2 будет Список.Вы не можете напрямую контролировать высоту строк, вы не можете изменить отступы вокруг представлений, вы не можете сказать, чтобы он отображал только столько строк и т. Д. Они не хотят, чтобы он был очень настраиваемым, потому что тогда каждое приложениесписки будут вести себя по-разному, отказываясь от цели стандартного элемента управления.

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

Ваша проблема

Возникает проблема, связанная с тем, что размер списка неникак не влияет на размер его рядов.SwiftUI не волнует, есть ли слишком много или слишком мало строк, чтобы соответствовать вашему предпочтительному размеру;он удачно изменит размер своих строк в соответствии с содержимым, даже если это означает, что они не все отображаются или отображаются пустые строки.

Если вам действительно нужно изменить размер строк в соответствии с размером их родителя, вам следуетиспользовать VStack.Если требуется прокрутка, вам нужно обернуть VStack в ScrollView.

Хакерское решение

Если вы все еще настаиваете на использовании списка, вам придетсясделайте что-то вроде следующего:

struct ContentView: View {

    @State private var textHeight: Double = 20
    let listRowPadding: Double = 5 // This is a guess
    let listRowMinHeight: Double = 45 // This is a guess
    var listRowHeight: Double {
        max(listRowMinHeight, textHeight + 2 * listRowPadding)
    }

    var strings: [String] = ["One", "Two", "Three"]

    var body: some View {
        VStack {
            HStack {
                Text(String(format: "%2.0f", textHeight as Double))
                Slider(value: $textHeight, in: 20...60)
            }
                VStack(spacing: 0) {
                    Color.red
                    List {
                        ForEach(strings, id: \.self) { item in
                            Text(item)
                                .font(.custom("Avenir Next Regular", size: 12))
                                .frame(height: CGFloat(self.textHeight))
                                .background(Color(white: 0.5))
                        }
                    }
                    // Comment out the following line to see how List is expected to work
                    .frame(height: CGFloat(strings.count) * CGFloat(self.listRowHeight))
                    Color.red
            }.layoutPriority(1)
        }
    }
}

Слайдер, чтобы показать, как высота строки списка изменяется с высотой их дочернего представления.Вам нужно будет вручную выбрать listRowPadding и listRowMinHeight, чтобы получить внешний вид, который наилучшим образом соответствует вашим ожиданиям.Если Apple когда-либо изменит внешний вид List (изменится отступы, минимальная высота строки и т. Д.), Вам придется не забывать возвращаться и корректировать эти значения вручную.

...