如何在 SwiftUI 中显示来自数据源(如 UITableView)的视图列表



在 SwiftUI 中,我们List表示可重用的项目。就像UIKit UITableView一样.

静态列表构建如下:

List {
    Text("cell")
    Text("cell")
    Text("cell")
    Text("cell")
}

但似乎它根本不可重复使用

如何拥有一些对象的数组并根据数组及其动态大小(计数(填充列表?

单元格被重用。请参阅 SwiftUI 中的列表是否重用类似于 UITableView 的单元格?

对于静态列表,限制为 10 个项目。这与ViewBuilder实现有关。

extension ViewBuilder {
    public static func buildBlock<C0, C1>(_ c0: C0, _ c1: C1) -> TupleView<(C0, C1)> where C0 : View, C1 : View
}
…
extension ViewBuilder {
    public static func buildBlock<C0, C1, C2, C3, C4, C5, C6, C7, C8, C9>(_ c0: C0, _ c1: C1, _ c2: C2, _ c3: C3, _ c4: C4, _ c5: C5, _ c6: C6, _ c7: C7, _ c8: C8, _ c9: C9) -> TupleView<(C0, C1, C2, C3, C4, C5, C6, C7, C8, C9)> where C0 : View, C1 : View, C2 : View, C3 : View, C4 : View, C5 : View, C6 : View, C7 : View, C8 : View, C9 : View
}

要使用数组,您可以使用以下 API:


let array = [1,2,3,4]
let listView = List(array) { value in
    Text(value.description)
}
extension List {
extension List {
    /// Creates a List that computes its rows on demand from an underlying
    /// collection of identified data.
    @available(watchOS, unavailable)
    public init<Data, RowContent>(_ data: Data, selection: Binding<Selection>?, rowContent: @escaping (Data.Element.IdentifiedValue) -> RowContent) where Content == ForEach<Data, HStack<RowContent>>, Data : RandomAccessCollection, RowContent : View, Data.Element : Identifiable
…

通常由动态数据生成的动态视图。因此,您应该考虑为重复视图使用数据结构,然后基于如下数据构建列表:

struct Student: Identifiable {
    let name: String
    let id: Int
}
struct ContentView : View {
    // Could be `@State Var` instead
    let students = [
        Student(name: "AAAAA", id: 1),
        Student(name: "BBBBB", id: 2),
        Student(name: "CCCCC", id: 3), // Notice that trailing comma is not problem here? 
    ]
    var body: some View {
        List(students) { student in
            Text(student.name)
        }
    }
}

数组应包含Identifiable对象(推荐(

或者,如果您不喜欢遵守Identifiable协议,则可以像这样使用它:

struct Book {
    let anyPropertyName: String
    let title: String
}
struct ContentView : View {
    // Could be `@State Var` instead
    let books = [
        Book(anyPropertyName: "AAAA", title: "1111"),
        Book(anyPropertyName: "BBBB", title: "2222"),
        Book(anyPropertyName: "CCCC", title: "3333")
    ]
    var body: some View {
        List(books.identified(by: .anyPropertyName)) { book in
            Text(book.title)
        }
    }
}

请注意,数据源可以@State var,并且能够在任何@State var更改时更新 UI。

最后,虽然看起来不是重用,但实际上确实如此!10 个静态项的限制与重用无关。

最新更新