6

Im my app I have a ScrollView with a LazyVStack inside.

The ForEach inside takes an array of DailyEvents:

struct DailyEvents: Equatable, Identifiable { var id: String { dayString + "\(events.count)" } let day: Date let events: [EventInfo] var isToday: Bool { day.isToday() } var dateString: String { DateFormatter.dayMonthDateFormtter.string(from: day) } var dayString: String { isToday ? "today".localized : DateFormatter.dayDateFormtter.string(from: day) } } 

So every time I add a new DailyEvents in the array, the LazyVStack updates properly.

But if I add a new EventInfo inside the events property of a DailyEvents already existing. The LazyVstack does not see the update and it does not reload.

If I switch LazyVstack for a VStack, everything works properly.

UI:

@ObservedObject var viewModel: ViewModel var scrollViewProxy = ScrollViewProxyManager() @SwiftUI.State private var isBackToTodayVisible = false private var events: [DailyEvents] { viewModel.dailyEvents.value ?? [] } var eventsList: some View { ZStack(alignment: .bottom) { ScrollView { ScrollViewReader { proxy in LazyVStack(alignment: .center, spacing: 0) { Spacer() .frame(height: 16) ForEach(events, id: \.id) { dailyEvent in makeDailyEvents(dailyEvent) } } .onAppear { scrollViewProxy.setProxy(proxy: proxy) } } } if isBackToTodayVisible { scrollTodayButton .padding(.bottom, 16) } } } 
3
  • Would you show how do you do the update, your events are constant property? Commented Jun 4, 2021 at 11:25
  • Computable properties do not update body, there should be stored dynamic property. Commented Jun 4, 2021 at 11:44
  • 2
    nope, I just remove the computed property, and I still have the same problem... I get the updates only if I scroll up and down Commented Jun 4, 2021 at 12:00

1 Answer 1

11

There is no alternative to UIKit UITableView's reloadData() method in SWIFTUI, to reload list/LazyStack data.

I faced exactly the same issue where the List or LazyVStack UI not updated when data-source updates.[here data-source should be @ObservedObject/@State]

I used a simple trick which fixed this issue -- assign a Unique ID to the view like below.

List(items, id: \.self) { Text($0.name) } .id(UUID()) 

Example with LazyVStack:

LazyVStack { ForEach(items, id: \.self) { item in Text(item.name) } } .id(UUID()) 
Sign up to request clarification or add additional context in comments.

1 Comment

Broooo that hoops I had to jump to get my data to refresh and this id was all I needed 😭

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.