Search code examples
swiftuiobservableswiftui-listonappear

The List View show empty when the data load on onAppear of the view in swiftUI


when I load data and set to @Published on onAppear of view in swiftUI, the List view had been rerender and loop each data but the list view is show empty

this is my struct for @Published

struct AddNewSongState {
    var arrayMP3File: [MP3File] = []
    var selectedCount: Int = 0
    var isLoaded: Bool = false
}

** and this is my ObservableObject class**

final class AddNewSongsHandler: ObservableObject {
    @Published private(set) var state: AddNewSongState
    
    let playlist: Playlist?
    init(state: AddNewSongState = .init(), playlist: Playlist?) {
        self.state = state
        self.playlist = playlist
    }

    func loadListSong() {
        state.arrayMP3File = DocumentFileManager.shared.loadMP3File()
    }
........
}

I declare on my class

struct AddNewSongsView: View {
    // MARK: - PROPERTIES
    @Environment(\.presentationMode) private var presentationMode
    @ObservedObject var handler: AddNewSongsHandler
    
    var body: some View {
        VStack {
            .......
               List {
                    ForEach(handler.state.arrayMP3File.indices, id: \.self) { index in
                        Button {
                            handler.send(intent: .toggleSelectedAt(index: index))
                            
                        } label: {
                            SongItemView()
                            .......
                    }
                }
                .modifier(ListBackgroundModifier())
                .cornerRadius(8, corners: .allCorners)
        } // VStack
        .background(Color.black)
        .navigationBarHidden(true)
        .onAppear {
            handler.send(intent: .loadListSong)
        }
    }
}

** The view had been rerender with the data correctly but the List view dont show any SongItemView()

but when i load the list song on the init AddNewSongsHandler the List view is showing correctly **


Solution

  • I found the cause of my error, in my code when passing the handler to AddNewSongsView I create an handler and passing it withthout any variable to save that instance

    AddNewSongsView(viewModel: AddNewSongsViewModel(...))
    

    and when I try create an instance to hold the AddNewSongsViewModel the bug is Gone . In the parent view of AddNewSongsView:

    @ObservedObject var viewModel: PlaylistViewModel
    @StateObject var addNewsSongVM: AddNewSongsViewModel
    init(viewModel: PlaylistViewModel) {
         self.viewModel = viewModel
         self._addNewsSongVM = StateObject(wrappedValue: AddNewSongsViewModel(playlist: viewModel.state.playlist))
        }
    

    and then you just need to pass to the AddNewSongsView

    Im still confuse how dose it work? if anyone know please add comment or answer in this question, thank you so much