Home > database >  Using onAppear on ForEach
Using onAppear on ForEach

Time:01-05

I created View which contains List and under List is Section:

struct SwiftUIView: View {
var body: some View {
    List {
        Section {
            EmptyView()
        } header: {
            Text("Some header text")
        }
        
        NewView()
    }
}
}

NewView and SomeViewModel code:

class SomeViewModel: ObservableObject {
    @Published var data: [String] = []

    func onAppear(){
        data = ["One", "Two", "Three"]
    }
}

struct NewView: View {

     @State private var viewModel = SomeViewModel()

     var body: some View {
        ForEach(viewModel.data, id: \.self){
                Text($0)
            }
            .onAppear(perform: viewModel.onAppear)
    }
}

Problem here is that onAppear modifier is not called on ForEach. When I added Text and use onAppear modifier on it, then it is working, but I don't need one more View. I tried to use EmptyView also, but again, onAppear is not called. Is there any way to call modifiers on ForEach?

CodePudding user response:

Try this approach to call onAppear()

struct ContentView: View {
    var body: some View {
        NewView()
    }
}

class SomeViewModel: ObservableObject {
    @Published var data: [String] = []
    
    func onAppear() {
        data = ["One", "Two", "Three"]
        print("----> in SomeViewModel onAppear")
    }
}

struct NewView: View {
    @StateObject var viewModel = SomeViewModel() // <-- here
    
    var body: some View {
        ForEach(viewModel.data, id: \.self){
            Text($0)
        }
        .onAppear{
            viewModel.onAppear()  // <-- here
        }
    }
}

CodePudding user response:

I think you should use init instead of onAppear to init the model

class SomeViewModel: ObservableObject {
    @Published var data: [String] = []

    init() {
        data = ["One", "Two", "Three"]
    }
}

struct NewView: View {

     @State private var viewModel = SomeViewModel()

     var body: some View {
        ForEach(viewModel.data, id: \.self){
                Text($0)
        }
    }
}
  • Related