尽管属性已更改,应用程序不会立即更新视图

Posted

技术标签:

【中文标题】尽管属性已更改,应用程序不会立即更新视图【英文标题】:App do not update view immediately though the property has been changed 【发布时间】:2020-01-15 13:04:40 【问题描述】:

我会很感激如何处理这个问题的实用建议,因为我完全迷路了。

我有一个 Contentview 为用户呈现一个任务和三个带有答案选项的按钮。选择任何选项,无论答案对错,用户都会立即得到响应,并立即提出新任务。此外,还有三个计数器,用于计算每个会话的一般回答任务数,以及每个会话的正确和错误答案数。

我还有一个开关,负责修复以下任务的条件之一。

问题是,一旦我点击了这个开关,它就会接受一个新值,但只有在用户回答旧任务后才会反映在新任务上。简单地说,它只适用于下一个任务,但我希望立即将视图更新为具有此固定条件的新任务,并且在切换之前呈现的任务不会被视为答案。

ContentView.swift

    import SwiftUI
    import Combine

    struct ContentView: View 

        @EnvironmentObject var myVM: MyViewModel

        var body: some View 

            VStack (spacing: 5) 

                TitleView()

                Spacer()

                CountersAndToggleView()

                MainTaskView(numberOfPlayersInText: self.myVM.multiplayer, figureOne: self.myVM.figureOne, figureTwo: self.myVM.figureTwo)

                AnswerOptionsButtonsRow(option1: self.myVM.answerOpt_1, option2: self.myVM.answerOpt_2, option3: self.my.answerOpt_3, correctAnswer: self.my.correctAnswer)

         
      

CountersAndToggleView.swift

    import SwiftUI
    import Combine

    struct CountersAndToggleView: View 

        @EnvironmentObject var myVM: MyViewModel


        var body: some View 
            HStack 
                VStack 

                        CounterView(counter: myVM.masterCounter, progressIndicatorColor: .gray, backGroundColor: .white)
                        HStack 
                        CounterView(counter: myVM.correctCounter, progressIndicatorColor: .green, backGroundColor: .white)
                        CounterView(counter: myVM.wrongCounter, progressIndicatorColor: .red, backGroundColor: .white)
                    
                

                Spacer()

                VStack 
                    Text("Fix multiplayer")
                        .font(.system(size: 15, design: .rounded))

                    VStack 

                        Toggle("Multiplyer", isOn: $myVM.multiplayerFixed)
                                .labelsHidden()
                                         
                
            
            .padding(.horizontal, 45)
        

myViewModel.swift

    import SwiftUI
    import Combine

    final class MyViewModel: ObservableObject 

        @Published var multiplayer: Int = 1

        @Published var figureOne: String = ""
        @Published var figureTwo: String = ""

        @Published var masterCounter = 0
        @Published var correctCounter = 0
        @Published var wrongCounter = 0

        @Published var multiplayerFixed: Bool = False

        init() 
             self.generateFigures()
             self.randomMultiplayer()
        

        .... other functions
        

我希望一旦 CountersAndToggleView 中的 multiplayerFixed 发生变化,ContentView 中的 mainTaskView 将完全更新,假设多人游戏的新数字和价值是固定的。

正如我所写,实际上它仅在用户回答之前的任务并按下按钮后才会发生。

你能告诉我我做错了什么吗?以及应该改变什么?

提前谢谢你。

【问题讨论】:

【参考方案1】:

在玩过代码后,我意识到解决方案应该是什么样子。其实myViewModel.swift需要做两件事:

    应声明属性 didChange
    var didChange = PassthroughSubject<Void, Never>()
    @Published var multiplayerFixed: Bool = False 属性应使用 didSet 进行更改
    var multiplayerFixed: Bool = false didSet reloadView()
    reloadView 函数是一个简单的函数,包括在 multiplayerFixed 更改后需要执行的任何代码。就我而言:
    func reloadView() 
           self.generateFigures()
           self.randomMultiplayer()
     

就这么简单。

【讨论】:

以上是关于尽管属性已更改,应用程序不会立即更新视图的主要内容,如果未能解决你的问题,请参考以下文章

语言更改后立即访问 CurrentInputLanguage 属性不会更新

更新角度变量后,视图不会在移动应用程序上更新,尽管它适用于浏览器

嵌套 ObservedObject 中的更改不会更新 UI

在更新时跟踪 NSManagedObject 属性并立即更新视图

更改托管对象属性不会触发 NSFetchedResultsController 更新表视图

模型更改时视图中的列表不会更新