I am stuck with little problem , I can not change the value with .onAppear(), .onTapGesture() function and with a NavigationLink in SwiftUI
If anyone can tell me how to solve it ? Regards,
VIEW ONE
struct ContentView: View {
@StateObject var vm = ViewModel()
var body: some View {
NavigationView{
List{
ForEach(0..<4){ numero in
NavigationLink(
destination: DetailView().onAppear(){
//This function is not working
vm.takeNumber(number: numero)
},
label: {
Text(String(numero))
})
}
}
}
}
}
class ViewModel: ObservableObject {
@Published var numero:Int = 0
func takeNumber(number: Int) {
numero = number
}
}
VIEW TWO
struct DetailView: View {
@StateObject var vm = ViewModel()
var body: some View {
// My number is not updated
Text(String("My NUMBER : \(vm.numero)"))
}
}
CodePudding user response:
@StateObject creates a fresh copy of your model.
Try changing it to
@ObservedObject var model: ViewModel
in DetailView and pass it as argument in ContentView.
CodePudding user response:
It looks like your approach is a bit incorrect. You are creating a new instance of your ViewModel within each view. To correctly pass the StateObject's instance forward, you will need to set it as an ObservedObject in your DetailView. StateObject should be your source of truth for this view model. I suggest reading up on the fundamentals of these property wrappers.
For this code to work, the onAppear should live within your DetailView. Within the detail view, call your takeNumber function with your number passed from your for loop. Then, reference your published value in your detail view. Viola!
struct ContentView: View {
@StateObject var vm = ViewModel()
var body: some View {
NavigationView{
List{
ForEach(0..<4){ numero in
NavigationLink(
destination: DetailView(vm: vm, number: numero),
label: {
Text(String(numero))
})
}
}
}
}
}
struct DetailView: View {
// Updated to observed object
// note how we are not constructing a new object here
@ObservedObject var vm: ViewModel
// Passing our number forward from our loop written in contentview
let number: Int
var body: some View {
// My number is not updated
Text(String("My NUMBER : \(vm.numero)"))
.onAppear {
vm.takeNumber(number: number)
}
}
}
class ViewModel: ObservableObject {
@Published var numero:Int = 0
func takeNumber(number: Int) {
numero = number
}
}
