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

时间:2020-01-15 13:04:40

标签: ios swift mvvm swiftui

由于我完全迷失了我,我将不胜感激如何处理此问题的实用建议。

我有一个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将被完全更新,并假设生成了新的数字并确定了multiplayer的价值。

正如我所写,实际上只有在用户回答了先前的任务和按钮之后,这种情况才会发生。

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

谢谢。

1 个答案:

答案 0 :(得分:0)

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

  1. 应将didChange属性声明为
    var didChange = PassthroughSubject<Void, Never>()
  1. @Published var multiplayerFixed: Bool = False属性应使用didSet进行更改
    var multiplayerFixed: Bool = false {didSet {reloadView()}}
  1. reloadView函数是一个简单的函数,其中包含更改multiplayerFixed后需要完成的所有代码。就我而言:
    func reloadView() {
           self.generateFigures()
           self.randomMultiplayer()
    } 

就这么简单。