I have a question regarding the architecture of my Swift / SwiftUI app consisting of a ListView, detail views and the detail views hold 2 input views. Specifically I want to know if this is the right way to do it.
The architecture is as follows:
The list view initiates a @StateObjct of the view model controller.
@StateObject var viewModel = ListViewModelController()
View model controller:
class ListViewModelController: ObservableObject {
@Published var model: ListViewModel
init() {
self.model = ListViewModel()
}
}
The List view model looks as follows:
struct Exercise: Hashable, Identifiable {
let id = UUID()
var name: String
var weight: String
var repetitions: String
}
struct ListViewModel {
var exercises = [
Exercise(name: "crunches", weight: "80 kg", repetitions: "100"),
Exercise(name: "curls", weight: "10 kg", repetitions: "12"),
Exercise(name: "dips", weight: "Bodyweight", repetitions: "10")
]
}
I pass the exercise variable to the detail view in the following way:
List {
ForEach($viewModel.model.exercises, id: \.self) {$exercise in
ExerciseConfigutationView(exercise: $exercise)
}
.onDelete(perform: delete)
.onMove(perform: move)
}
The detail view accepts the exercise variable as a binding:
@Binding var exercise: Exercise
The problem is, every time I try to present the ListView, the programm freezes without a warning or error. I assume I have misunderstood something about the binding / property wrappers.
Thanks for your help.
@Bindingshould only be used if you plan to modify the value within your view and you want those changes persisted in some other place. If you're only reading the data just change it to aletexpression. SwiftUI will still update the view when the data changes if your variable is@Published.