【问题标题】:Big SwiftUI List on MacOS not fluidMacOS 上的大 SwiftUI 列表不流畅
【发布时间】:2021-01-31 15:36:13
【问题描述】:

我在 MacOS 上的 SwiftUI 应用程序中有一个列表,例如10.000 个条目。
尝试像下面的示例非常慢。

.id(UUID()) 添加到列表中,这是在之前的帖子中建议的,它会更快一些,但仍然不流畅。
更糟糕的是,将 .id(UUID()) 添加到列表中,然后无法通过箭头键(上/下)导航列表。

有没有更好的方法来实现这一点?

struct TestViews_MacOS_BigList: View {
  @State var selectedItem: String?
  var items: [String]

  var body: some View {
    List(items,id: \.self, selection: $selectedItem ) { item in
      Text("\(item)").tag("\(item)")
    }
    //.id(UUID())
  }
}

func testnames()->[String]{
  var list: [String] = []
  for i in 1...10000 {
    list.append("Sting Nr \(i)")
  }
  return list
}

【问题讨论】:

    标签: macos swiftui


    【解决方案1】:

    Views 太多了,不能坐在那里。您需要使用 CoreData 或其他手动方式来 Batch load 项目,并且一次只能拥有一定数量的 Views/items fetched/loaded

    一个指定批量大小的NSFetchedResultsController 可以帮助解决这个问题

    let fetchRequest: NSFetchRequest<Item> = NSFetchRequest<Item>(entityName: "Item")
        fetchRequest.includesPendingChanges = false
        fetchRequest.fetchBatchSize = 20
    

    执行获取时,会评估整个请求并记录所有匹配对象的身份,但一次只会从持久存储中获取最大为 batchSize 的对象的数据。

    @FetchRequest 也可以这样做,它是为 SwiftUI 制作的,因此它应该进行补偿,但文档没有指定。

    【讨论】:

    【解决方案2】:

    尝试使用 LazyVStack,因为它可以有效地使用内存,如下所示:

    struct TestViews_MacOS_BigList: View {
     @State var selectedItem: String?
     var items: [String]
     var body: some View {
      ScrollView {
       LazyVStack{
        ForEach(items, id: \.self, content: { item in
         HStack{
          Button(action: {
           selectedItem = item
          }, label: {
           Text("Select ")
          })
          Text("\(item)").tag("\(item)")
        }
      })
     }
    }
    

    }

    }

    【讨论】:

    • 列表在 SwiftUI 2 中是惰性的
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-20
    • 1970-01-01
    • 2020-10-10
    • 2021-03-30
    • 2020-04-11
    • 1970-01-01
    相关资源
    最近更新 更多