bjorn.lau
bjorn.lau

Reputation: 1188

How to fetch data when TabView page is selected in SwiftUI

I am trying to fetch a CoreData object when my TabView (page style) gets displayed based on an ID I send to the view from the TabView ForEach.

TabView(selection: $tabSelection) {
        ForEach(Array(balloons.enumerated()), id: \.element) { index, balloon in
            BalloonView(balloon: balloon, balloonID: balloon.id)
                .tag(index)
        }
    }

So each tab gets the balloonID sent correctly to the BalloonView then what I have been trying to do on the view is: call my ViewModel from BalloonView using .task that then fetches the CoreData object and puts it in a @Published var that I listen for in the view. (Basicaly a normal MVVM pattern, I think?).

This works fine if I just use a NavigationLink and navigate the view. But when I do it inside the TabView as showed above it's very unstable since it seems this .task is called multiple times and as soon as you slide a little to the page.

I am new to SwiftUI, and I have a sense that the state variable: $tabSelection on the TabView could solve it somehow. I just can't figure out how I can call my viewModel and tell it to fetch the CoreData object when the $tabSection is changed to whatever ID?

Hope it makes sense, any help is appreciated.

ViewModel:

@Published var myBalloon: MyBalloon?    

func getBalloonBy(id: String) {
    myBalloon = coreDataManager.getBalloonFrom(id: id)
}

View:

@EnvironmentObject var balloonViewModel: BalloonViewModel

if let note = balloonViewModel.myBalloon?.note?.description {
    Text("Note: \(note)")
}

.task {
    balloonViewModel.getBalloonBy(id: balloonID)
}

Upvotes: 0

Views: 618

Answers (1)

bjorn.lau
bjorn.lau

Reputation: 1188

Thanks to @jnpdx I figured it out. .onChange(of: tabSelection) { [tabSelection] newState in } did the trick, since I was now able to call my CoreData function based on the change of page instead on .onAppear

Upvotes: 0

Related Questions