UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

SOLVED: List row not updating

Forums > SwiftUI

Row view is not updating. Can someone help me please?I made simplified version of my actual code.

struct Job: Codable, Identifiable, Equatable, Hashable {
    public var id: Int
    public var jobName: String
    public var otherInformation: String

    //...other code for coding and decoding json...
}

class JobsArray: ObservableObject {
    @Published var jobs: [Job] = []
}

struct JobsListView: View {
    @EnvironmentObject var appContainer: AppContainer
    @StateObject var jobsArray = JobsArray()

    func initializeData() {
        //first initializes cached data
        jobsArray.jobs = appContainer.getCachedData()
        //then it tries to fetch data from the endpoint. each time it fetches, the
        //data can be different.
        appContainer.fetchData() { fetchedJobs
            DispatchQueue.main.async {
                jobsArray.jobs = fetchedJobs
            }
        }
    }

    var body: some View {
        ZStack(alignment: bottom) {
            List(jobsArray.jobs) { job in
                //Text(job.jobName) THIS WORKS FINE
                JobCardRowView(job) //THIS DOESN'T
            }
            .onAppear(perform: {
                initializeData()
            })
        }
    }
}

struct JobCardRowView: View {
    var job: Job

    var body: some View {
        HStack {
            Text(job.jobName)
        }
    }
}

It works with:Text(job.jobName) But not with:JobCardRowView(job) With the second line the view just freezes with the first data, but it won't update. What's the problem here?Thanks.

2      

I'm honestly surprised that even compiles.

This line:

JobCardRowView(job)

should be:

JobCardRowView(job: job)

And this line:

appContainer.fetchData() { fetchedJobs

should be:

appContainer.fetchData() { fetchedJobs in

2      

hi,

SwiftUI is basically in the business of creating and deleting Views (structs), and eventually rendering them on screen. it keeps track of all Views (structs) it has created, basically, by an identification system (likely) involving some combination of UUIDs and hash values.

when you have two Views (structs) such as Text("Swift") and Text("UI"), SwiftUI is then in the business of managing two structs that it knows are distinct, because simple Text views are distinct if their strings are distinct.

those Views (structs) remain in existence and are used by SwiftUI until one of two things happens:

  • SwiftUI destroys the View on its own (e.g., you have a long list and scroll something far enough off-screen that SwiftUI decides it's easier to throw the View away and recreate it later when that something comes back on-screen)
  • SwiftUI discovers that a View (struct) is no longer valid and it destroys it (creating a new one in its place, perhaps)

so ... when you write

List(jobsArray.jobs) { job in
  Text(job.jobName)
}

SwiftUI creates some Text views that are identified by the values of job.jobName. change a job's name and SwiftUI will see that there's been a change. the "old" text view will be removed and a "new" text view will be created and (eventually) drawn.

when you write

List(jobsArray.jobs) { job in
  JobCardRowView(job)
}

SwiftUI creates some JobCardRowView Views (structs) that are identified by the values of job.id ... because you made them Identifiable. change a job's id (or, add a new one or delete an existing one) and SwiftUI will see that there's been a change; but change a job's name and SwiftUI has no reason to throw out a View (struct) it already has for that id

consider passing the jobsArray as an @ObservedObject to JobCardRowView as well as the index of the job to display (and not the job itself). reloading the jobsArray at any time will not cause SwiftUI to destroy/recreate the JobCardRowView struct, but it will trigger a re-render of the JobCardRowView.

hope that helps,

DMG

4      

Hacking with Swift is sponsored by Essential Developer

SPONSORED Join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer! Hurry up because it'll be available only until April 28th.

Click to save your free spot now

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.