SwiftUI 视图更新 [英] SwiftUI View updating
问题描述
我有:
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只有在ExciseProgram的currentExercise发生变化时才会更新,而currentExercise本身就有一个currentSet属性,当它发生变化时,我的view没有更新.原则上,我理解为什么我们按照它的工作原理工作的逻辑:我指定了当 currentExercise 更改时应该更新视图,但我没有说当 currentExercise 实体的属性更改时应该更新视图.所以我不明白该怎么做.而且我不能把运动改成结构体
The problem is that my View is updated only when the currentExercise of the ExerciseProgram changes, and the currentExercise itself has a currentSet property, and when it changes, my view is not updated. In principle, I understand the logic of why we work exactly as it works: I specified that the view should be updated when currentExercise changes, but I did not say that the view should be updated when the properties of the currentExercise entity change. And so I don't understand how to do it. And I can't change Exercise as struct
推荐答案
您只需要在适当的级别观察对象即可.
You just have to observe the object at the appropriate level.
每个 @Published
仅在对象整体发生变化时触发刷新.
Each @Published
only triggers a refresh if the object as a whole has changed.
在您的示例中,如果您替换数组或添加/删除对象,数组将会更改.
In you example the array will change if you replace the array or add/remove objects.
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
}
}
另外,注意 ObservableObject
是如何被初始化的.
Also, notice how the ObservableObject
s have been initialized.
@StateObject
当对象必须在 View
@ObservedObject
用于将 ObservableObject
传递给子 View
,但该对象是在 class
内创建的>,特别是类的练习程序
.
@ObservedObject
is used to pass an ObservableObject
to a child View
but the object was created inside a class
, specifically class ExerciseProgram
.
https://developer.apple.com/documentation/swiftui/managing-model-data-in-your-app
这篇关于SwiftUI 视图更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!