首页 > 解决方案 > SwiftUI TabView Page 如何处理大数据

问题描述

我用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))

标签: swiftuitabview

解决方案


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

正如我到目前为止所发现的(真的希望我错了),您可以在不加载所有内容的情况下滑动页面选项卡视图的唯一方法是@State仅用于索引(将您的替换为from之$assetModel.identifier类的东西)。$identifier@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))
        }
    }
}

推荐阅读