分享
三行代码  ›  专栏  ›  技术社区  ›  LGX

@同一视图中的ObservedObject ViewModel和@EnvironmentObject会导致计时器问题

  •  0
  • LGX  · 技术社区  · 1 周前

    我是一个新的SwiftUi开发者,我很喜欢它。我试过一些东西,现在我的代码出现了一种奇怪的行为,更具体地说是关于UI更新。

    我的视图-视图模型代码

    class UUIDViewModel : ObservableObject {
        var timer: Timer?
        @Published var i = 0
        @Published var text = UUID.init().uuidString
        
        func generateUUID() -> Void {
            self.i = 0
            self.timer = Timer.scheduledTimer(withTimeInterval: 3, repeats: true) { (timer) in
                print(self.i)
                self.text = UUID.init().uuidString
                if self.i == 5 {
                    self.timer?.invalidate()
                }
                self.i = self.i + 1
            }
        }
    }
    
    struct FirstView: View {
        
        @ObservedObject var uuidVm = UUIDViewModel()
        @EnvironmentObject var tabBarVM: TabBarViewModel
        
        var body: some View {
            VStack {
                Button("start", action:  { 
                    tabBarVM.hasNotification = true
                    uuidVm.generateUUID()
                })
                Text(uuidVm.text)
                    .padding()
                    .font(.system(size: 30, weight: .bold, design: .rounded))
            }
    
        }
    }
    
    struct FirstView_Previews: PreviewProvider {
        static var previews: some View {
            FirstView()
        }
    }
    

    这里是带有TabBar的主视图,这里的目标是在单击另一个视图的start按钮时更新TabBar项文本。

    当没有注射 ,用户界面用新的uuid更新了5次。 但是当我注入ViewModel时,计时器启动了,tabBar中的文本也启动了,但是 第一视图

    我错过什么了吗?谢谢!

    
    class TabBarViewModel : ObservableObject {
        @Published var hasNotification = false
    
    }
    
    struct ContentView: View {
        
        @ObservedObject var tabBarVM = TabBarViewModel()
        @State private var selection = 0
        
        init() {
            UITabBar.appearance().barTintColor = .white
        }
        
        var body: some View {
            TabView(selection: $selection,
                    content: {
                        FirstView()
                            .tabItem {
                                Image(systemName: "house.fill")
                                Text(tabBarVM.hasNotification ? "Notif" : "Home")
                            }.environmentObject(tabBarVM)
    
                        Text("Bookmark Tab")
                            .font(.system(size: 30, weight: .bold, design: .rounded))
                            .tabItem {
                                Image(systemName: "bookmark.circle.fill")
                                Text("Bookmark")
                            }
    
                        Text("Video Tab")
                            .font(.system(size: 30, weight: .bold, design: .rounded))
                            .tabItem {
                                Image(systemName: "video.circle.fill")
                                Text("Video")
                            }
    
                        Text("Profile Tab")
                            .font(.system(size: 30, weight: .bold, design: .rounded))
                            .tabItem {
                                Image(systemName: "person.crop.circle")
                                Text("Profile")
                            }
                    })
        }
    }
    
    struct ContentView_Previews: PreviewProvider {
        static var previews: some View {
            ContentView()
        }
    }
    
    1 回复  |  直到 1 周前
        1
  •  0
  •   Raja Kishan    1 周前

    将ObservedObject更改为StateObject。

    struct FirstView: View {
        
        @StateObject var uuidVm = UUIDViewModel() //<--Here
        @EnvironmentObject var tabBarVM: TabBarViewModel
    
       //Other body code 
    }
    

    另一种方法是移除 @ObservedObject 从tabBar视图看,不需要 @ObservedObject .

    struct ContentView: View {
        
        var tabBarVM = TabBarViewModel() //<-- Here
        
        //Other code
    }