SwiftUI多列表视图数据加载与@AppStorage状态保存问题
解决SwiftUI列表数据区分与状态独立保存问题
一、从关联ObservableObject拉取不同列表的专属数据
目前两个列表数据完全相同,核心原因是你未在ObservableObject中区分两类列表的数据源,或者在视图中错误复用了同一组数据。按以下步骤调整:
- 拆分ObservableObject中的数据源
假设关联的ObservableObject类名为MenuDataStore,在其中为两个列表分别定义独立的发布属性:
class MenuDataStore: ObservableObject { // 好友列表专属数据 @Published var friendshipItems: [MenuListItemModel] = [] // 财富列表专属数据 @Published var wealthItems: [MenuListItemModel] = [] init() { // 分别加载两类数据 loadFriendshipData() loadWealthData() } private func loadFriendshipData() { // 替换为你的好友数据加载逻辑(本地/网络) friendshipItems = [ MenuListItemModel(id: "f1", title: "好友A"), MenuListItemModel(id: "f2", title: "好友B") ] } private func loadWealthData() { // 替换为你的财富数据加载逻辑 wealthItems = [ MenuListItemModel(id: "w1", title: "活期账户"), MenuListItemModel(id: "w2", title: "基金持仓") ] } }
- 在视图中绑定对应数据源
如果是全局共享数据,推荐用@EnvironmentObject注入避免重复初始化:
- 在App入口注入:
@main struct YourApp: App { @StateObject private var dataStore = MenuDataStore() var body: some Scene { WindowGroup { MainTabView() // 你的主页面(包含两个列表的入口) .environmentObject(dataStore) } } }
FriendshipListView.swift中使用:
struct FriendshipListView: View { @EnvironmentObject private var dataStore: MenuDataStore var body: some View { List(dataStore.friendshipItems) { item in Text(item.title) } } }
WealthListView.swift中使用:
struct WealthListView: View { @EnvironmentObject private var dataStore: MenuDataStore var body: some View { List(dataStore.wealthItems) { item in Text(item.title) } } }
二、配置@AppStorage实现列表状态独立保存
@AppStorage通过唯一Key区分存储值,只要为两个列表的状态变量设置不同的Key,即可实现独立保存。
示例1:保存列表选中项
- 好友列表:
struct FriendshipListView: View { @EnvironmentObject private var dataStore: MenuDataStore // 专属Key:friendship_list_selected_id @AppStorage("friendship_list_selected_id") private var selectedId: String? var body: some View { List(dataStore.friendshipItems, id: \.id, selection: $selectedId) { item in Text(item.title) } } }
- 财富列表:
struct WealthListView: View { @EnvironmentObject private var dataStore: MenuDataStore // 专属Key:wealth_list_selected_id @AppStorage("wealth_list_selected_id") private var selectedId: String? var body: some View { List(dataStore.wealthItems, id: \.id, selection: $selectedId) { item in Text(item.title) } } }
示例2:保存列表滚动位置
- 好友列表:
struct FriendshipListView: View { @EnvironmentObject private var dataStore: MenuDataStore @AppStorage("friendship_list_scroll_offset") private var scrollOffset: CGFloat = 0 private let scrollViewProxy = ScrollViewReader { proxy in ... } var body: some View { ScrollView { // 列表内容 } .onChange(of: scrollOffset) { offset in proxy.scrollTo(offset, anchor: .top) } } }
- 财富列表:
struct WealthListView: View { @EnvironmentObject private var dataStore: MenuDataStore @AppStorage("wealth_list_scroll_offset") private var scrollOffset: CGFloat = 0 // 滚动逻辑同上 }
所有需要独立保存的状态,都遵循为每个列表设置唯一@AppStorage Key的原则即可。
内容的提问来源于stack exchange,提问作者Kraig Kistler
相关产品推荐
相关产品推荐

