【问题标题】:How SwiftUI TabView Page handles big dataSwiftUI TabView Page 如何处理大数据
【发布时间】:2021-07-31 10:17:34
【问题描述】:

我使用TabView浏览相册是因为我需要一个分页功能,但是我的相册有上千张图片,而TabView处理起来很慢。 有什么办法可以延迟加载,让 TabView 可以处理成千上万的数据。

TabView(selection: $assetModel.identifier) {
    ForEach(0..<7000) { index in
        let asset = assetModel.assetArray[index]
        AssetPreviewItemView(asset: asset)
            .tag(asset.localIdentifier) 
    }
}
.tabViewStyle(.page(indexDisplayMode: .always))
.indexViewStyle(.page(backgroundDisplayMode: .always))

【问题讨论】:

  • 很可能不是 TabView 很慢。 TabView 仅呈现一组视图,不处理您的任何数据方面,例如获取图像、缓存、预取等。将此逻辑放入模型或视图模型中 - 然后显示您拥有的内容。
  • @CouchDeveloper 感谢您的回复,我可以确定 TabView 很慢。如果将图片更改为彩色,它会冻结并变慢。因为太多,我有7000张照片。我觉得最好的办法就是懒加载,永远保持三张照片,这样最好。
  • 您是否已经发现了“LazyView”技巧:forums.swift.org/t/…?不过,您仍然必须考虑到所有视图都会调用 init。否则,你可以考虑使用好的旧 UIKit PageViewController。
  • 当您认为某件事使您的应用程序变慢时,请尝试将其删除,看看您是否正确。如果您尝试在没有 TabView 的情况下显示您的收藏,您会发现这不是问题。同样,如果没有您的代码,我们也无法为您提供帮助。
  • @Philip 感谢您的回复。我更新了代码。通过左右滑动页面浏览照片的视图。由于数据过多,速度较慢。

标签: swiftui tabview


【解决方案1】:

目前 (Xcode13.2.1),每次更改 TabView 的选择(每次滑动图像)时,TabView 都会初始化所有 7000 个 AssetPreviewItemView,这就是它如此滞后的原因。

到目前为止,我已经发现(真的希望我错了)您可以在不加载所有内容的情况下滑动浏览页面选项卡视图的唯一方法是仅将 @State 用于索引(将您的 $assetModel.identifier 替换为 @ 之类的东西987654323@ 来自@State var identifier)。

您可以在我的测试代码中看到每个滑动页面的 TestTabPageViewCell 初始化 7000 次:

import SwiftUI

struct TestTabPageView: View {
    @StateObject private var viewModel = TestTabPageViewModel()
    
    var body: some View {
        VStack {
            TabView(selection: $viewModel.index) {
                ForEach((0..<7000), id: \.self) { i in
                    TestTabPageViewCell(content: "\(i)").tag(i)
                }
            }
            .tabViewStyle(.page(indexDisplayMode: .always))
        }
    }
}

class TestTabPageViewModel: ObservableObject {
    @Published var index = 0
}

struct TestTabPageViewCell: View {
    var content: String
    init(content: String) {
        self.content = content
        print("init \(content)")
    }
    var body: some View {
        Text(content)
    }
}

要摆脱 7000 个初始化,您必须将索引保留为私人使用

struct TestTabPageView: View {
    @State var index = 0
    
    var body: some View {
        VStack {
            TabView(selection: $index) {
                ForEach((0..<7000), id: \.self) { i in
                    TestTabPageViewCell(content: "\(i)").tag(i)
                }
            }
            .tabViewStyle(.page(indexDisplayMode: .always))
        }
    }
}

【讨论】:

  • 你有没有测试,我没有看到核心变化
  • 当然可以,我已经更新了我的答案
猜你喜欢
  • 2022-12-27
  • 1970-01-01
  • 2020-05-22
  • 2022-01-20
  • 2021-07-06
  • 1970-01-01
  • 1970-01-01
  • 2013-12-24
  • 1970-01-01
相关资源
最近更新 更多