SwiftUI 在视图之间共享模型数据

Posted

技术标签:

【中文标题】SwiftUI 在视图之间共享模型数据【英文标题】:SwiftUI Sharing model data between views 【发布时间】:2021-01-16 12:23:41 【问题描述】:

我有这样的结构,我想问你的方法对我来说似乎是错误的。因此,当我想在 1 个视图中使用 2 个模型时,我必须将它放在一个视图中的 foreach 中。这就是我要的。在我想要的其他页面上使用我在用户个人资料中使用的数据。我该怎么做?你们是怎么做到的?

让我举个例子让你更好地理解:

我想在主页上显示我的用户的用户名数据,我应该怎么做?。事实上,在初始化我的模型一次之后,我想在其他视图中使用它。什么是正确的方法。

  import SwiftUI

struct ContentView: View 
    @StateObject var network = ProfileNetwork()
    var body: some View 
        TabView
            ProfileView().tabItem  Image(systemName: "house") 
            ForEach(self.network.userprofile,id:\.id)a in
                ShopView(profile_model: a)
            .tabItem  Image(systemName: "house") 
        
    


struct ContentView_Previews: PreviewProvider 
    static var previews: some View 
        ContentView()
    



class ProfileNetwork : ObservableObject 
    @Published var userprofile : [UserPRofile] = [UserPRofile(name: "Test", coin: 1, id: "dsa")]


struct ProfileView : View 
    @StateObject var network = ProfileNetwork()
    var body: some View 
        ForEach(self.network.userprofile, id:\.id) i in
            ProfileViewModel(profile_model: i)
        
    


struct ProfileViewModel : View 
    var profile_model : UserPRofile
    var body: some View 
        Text(self.profile_model.name)
    


struct UserPRofile : Decodable
    var name : String
    var coin : Int
    var id : String


class ShopeNetwork : ObservableObject 
    @Published var shop : [ShopStore] = [ShopStore(id: "sda", image: "dasd", price: 100, name: "sda")]


struct ShopView : View 
    @StateObject var network = ShopeNetwork()
    var profile_model : UserPRofile
    var body: some View 
        ForEach(self.network.shop, id:\.id) c in
            ShopViewModel(shop_model: c, profile_model: profile_model)
        
    


struct ShopViewModel : View 
    var shop_model : ShopStore
    var profile_model : UserPRofile
    var body: some View 
        Text(profile_model.name)
        Text(self.shop_model.name)
    



struct ShopStore : Decodable 
    var id : String
    var image : String
    var price : Int
    var name : String

【问题讨论】:

这里的首页有什么意义? 【参考方案1】:

一个可能的解决方案是创建一个@EnvironmentObject 并在根级别注入它:

class AppState: ObservableObject 
    @Published var userProfile: UserPRofile?

@main
struct TestApp: App 
    @StateObject private var appState = AppState()

    var body: some Scene 
        WindowGroup 
            ContentView()
                .environmentObject(appState)
        
    

struct ProfileView: View 
    @EnvironmentObject private var appState: AppState // access as an `@EnvironmentObject`
    @StateObject var network = ProfileNetwork()
    var body: some View 
        VStack 
            ForEach(self.network.userprofile, id: \.id)  i in
                ProfileViewModel(profile_model: i)
            
        
        .onAppear 
            appState.userProfile = network.userprofile.first // set `userProfile` globally
        
    

struct ShopView: View 
    @EnvironmentObject private var appState: AppState // use it in any other view
    ...

【讨论】:

【参考方案2】:

Swift 5、ios 14

将类设为单例,以便轻松共享。

class ProfileNetwork : ObservableObject 
    @Published var userprofile : [UserPRofile] = [UserPRofile(name: "Test", coin: 1, id: "dsa")]
    static var shared = ProfileNetwork()

然后用共享句柄引用它。

struct ContentView: View 
  @StateObject var network = ProfileNetwork.shared
  var body: some View 

....


struct ProfileView : View 
  @StateObject var network = ProfileNetwork.shared 
  var body: some View 

....

【讨论】:

以上是关于SwiftUI 在视图之间共享模型数据的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI之如何使用@EnvironmentObject在视图之间共享数据

在 SwiftUI MVVM 中的子视图和父视图之间共享值

如何在 SwiftUI 中的类和视图之间共享数据

SwiftUI 和 MVVM - 模型和视图模型之间的通信

如何在 SwiftUI 中创建共享导航栏以在多个视图之间进行交互? [关闭]

更改选项卡式视图栏颜色 SwiftUI