【问题标题】:SwiftUI View updatingSwiftUI 视图更新
【发布时间】:2021-08-09 10:43:46
【问题描述】:

我有:

class Exercise: ObservableObject {
  @Published var currentSet: Int = 1
  func start() { somehow changing currentSet }
}

class ExerciseProgram: ObservableObject {
  @Published var currentExercise: Exercise? = nil

  func start() { ...self.currentExercise = self.exercises[exerciseIndex + 1]... }
}

struct Neck: View {
  @ObservedObject var program: ExerciseProgram = ExerciseProgram(exercises: neckExercises)

  var body: some View {
    Text(\(self.program.currentExercise!.currentSet))
  }
}

问题是我的View只有在ExerciseProgram的currentExercise改变时才更新,而currentExercise本身有currentSet属性,当它改变时我的view没有更新。原则上,我理解为什么我们完全按照它的工作方式工作的逻辑:我指定了当 currentExercise 更改时应该更新视图,但我没有说当 currentExercise 实体的属性发生更改时应该更新视图。所以我不明白该怎么做。而且我不能将运动更改为结构

【问题讨论】:

标签: swift swiftui


【解决方案1】:

您只需要在适当的级别观察对象即可。

每个@Published 仅在对象整体发生变化时触发刷新。

在您的示例中,如果您替换数组或添加/删除对象,数组将会改变。

import SwiftUI
struct ExerciseProgramView: View {
    //At this level you will see the entire program
    @StateObject var program: ExerciseProgram = ExerciseProgram()
    
    var body: some View {
        VStack{
            if program.currentExercise != nil{
                ExerciseView(exercise: program.currentExercise!)
            }else{
                Text("Ready?")
            }
            Spacer()
            HStack{
                if program.currentExercise == nil{
                    Button("start program", action: {
                        program.start()
                    })
                }else{
                    Button("stop", action: {
                        program.stop()
                    })
                    Button("next", action: {
                        program.next()
                    })
                }
                
            }
        }
    }
}
struct ExerciseView: View {
    //At this level you will see the changes for the exercise
    @ObservedObject var exercise: Exercise
    
    var body: some View {
        VStack{
            Text("\(exercise.name)")
            Text("\(exercise.currentSet)")
            if exercise.timer == nil{
                Button("start exercise", action: {
                    exercise.start()
                })
            }else{
                Button("stop exercise", action: {
                    exercise.stop()
                })
            }
        }.onDisappear(perform: {
            exercise.stop()
        })
    }
}

struct ExerciseProgramView_Previews: PreviewProvider {
    static var previews: some View {
        ExerciseProgramView()
    }
}
class Exercise: ObservableObject, Identifiable {
    let id: UUID = UUID()
    let name: String
    @Published var currentSet: Int = 1
    var timer : Timer?
    init(name: String){
        self.name = name
    }
    func start() {
        timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true, block: { timer in
            
            self.currentSet += 1
            
            if self.currentSet >= 10{
                timer.invalidate()
                self.timer = nil
            }
            
        })
    }
    
    func stop(){
        timer?.invalidate()
        timer = nil
    }
}

class ExerciseProgram: ObservableObject {
    @Published var currentExercise: Exercise? = nil
    @Published var exercises: [Exercise] = [Exercise(name: "neck"), Exercise(name: "arm"), Exercise(name: "leg"), Exercise(name: "abs")]
    @Published var exerciseIndex: Int = 0
    func start() {
        self.currentExercise = self.exercises[exerciseIndex]
    }
    
    func next(){
        if exerciseIndex < exercises.count{
            self.exerciseIndex += 1
        }else{
            self.exerciseIndex = 0
        }
        start()
    }
    
    func stop(){
        exerciseIndex = 0
        currentExercise = nil
    }
}

另外,请注意ObservableObjects 是如何被初始化的。

@StateObject 用于必须在 View 中初始化对象时使用

@ObservedObject 用于将ObservableObject 传递给子View,但该对象是在class 中创建的,特别是 class ExerciseProgram

https://developer.apple.com/documentation/swiftui/managing-model-data-in-your-app

【讨论】:

    猜你喜欢
    • 2020-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-05
    • 2020-12-21
    • 2021-10-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多