您只需要在适当的级别观察对象即可。
每个@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