Searched around and have not found an answer. Believe I know what the issue is, but not sure how to resolve it.
I have a swiftUI list that displays a context menu when a certain type of row is selected(not all rows qualify, this works as it should. When the context menu is displayed, the label is generated by the index of the array populating the lists object property.
The context menu selection performs performs a task that should result in the context menu label changing. And sometimes it works, other times it does not. This is resolved by scrolling that particular row off screen and scrolling back too it (has to be far enough away). The Object array is from a singleton data store passed as an environment object.
I believe this is related to the size of the array and the data being lazy loaded in swiftUI lists. I also would use the List selection property for this, but the context menu being populated by the row does not update the lists selected row.
A snippet example of my code is below.
@EnvironmentObject var singletonStore: MyObjectStore
@State private var selectedRow: Int?
var body: some View {
VStack {
List(singletonStore.myArray.indices, id: \.self, selection: $selectedRow) { index in
LazyVGrid(columns: gridColumns) {
ItemGridView(item: $singletonStore.myArray[index], opacityOffset: getRowOpacity(index: index))
}
.contextMenu {
if singletonStore.myArray[index].thisDate == nil {
if singletonStore.myArray[index].thisNeedsDone > 0 {
Button {
selectedRow = index
//these functions will add or remove a users id or initials to the appropriate property, and this updates values in my list view.
if singletonStore.myArray[index].id != nil {
//do this
} else {
//do that
}
} label: {
Label{
//This is where my issue is - even though the items in the list view are updating, the label of the context menu is not updating until the row is reloaded
Text(singletonStore.myArray[index].initials != nil ? "This Label" : "That Label") } icon: {
Image(systemName: "aqi.medium")
}
}
}
}
} //context menu close
} // list close
.listStyle(PlainListStyle())
}
}
My closures may be off, but its because I modified the code significantly on this platform to make is easier to follow. Nothing removed would affect this issue.
if there was a way to have opening the context menu update the lists selected row, that would solve the issue and I could use the selected row for the index of the singletonStores array objects property, but I may be approaching the problem from thinking the index is incorrect when the actual issue is the context menu is not being reloaded with the environment objects new information. Any help is always appreciated!
EDIT:
After some tinkering I further found that the issue must be related to the context menu itself not refreshing its data. I separated my views and used a @Viewbuilder function to return the needed view for the button - however it still does not refresh the context menus data.
EDIT 2:
currently (and subject to change) my SingletonStore class loads the data from another network class and publishes that data in the form of an array
final class SingletonStore: ObservableObject {
static private(set) var shared = singletonStore()
static func reset() {
shared = StagingStore()
}
@Published var myArray: [CustomObject] = []
private func getMyData() {
//uses other class and methods to retrieve and set data
//works and updates view on refresh
}
}
My View is called from a different View that is just a Tab bar controller, that code looks as follows:
struct ContainerView: View {
@StateObject var singletonStore = SingletonStore.shared
var body: some View {
TabView{
GenericView().environmentObject(singletonStore)
.tabItem {
Label("This View", systemImage: "camera.metering.matrix")
}
}
}