简体   繁体   中英

SwiftUI: LazyVStack does not update

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)
                }
            }
        }

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())

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM