I want to record long term, how many times a specific ItemView
has been displayed in my TabView below. Each time a user swipes on the tab, I want to update var timesViewed
by 1. However, timesViewed
doesn't seem to update and I am really stuck as to why now. I am a SwitUI noob, so thanks for the patience!
I removed some view modifiers to simplify the code below.
struct Item: Identifiable, Hashable, Codable {
var id = UUID()
var title: String
var detail: String
var repeatOn: String
var timesViewed = 0
mutating func viewedThisItem() {
timesViewed = 1
}
}
struct ItemSessionView: View {
var itemViewModel: ItemListVM
@State var count = 0
@State var currentIndex = 0
var body: some View {
let today = getTodaysDate().uppercased()
var tempList = itemViewModel.list.filter({ return $0.repeatOn == today})
ZStack {
GeometryReader { proxy in
TabView(selection: $currentIndex) {
ForEach(tempList) { item in
Group {
if today == item.repeatOn {
ItemDetailView(item: item)
}
}
}
}
.onChange(of: currentIndex) { value in
tempList[currentIndex].viewedThisItem()
}
}
}
}
func getTodaysDate() -> String {
let today = Date.now
let formatter = DateFormatter()
formatter.dateStyle = .short
formatter.timeStyle = .medium
formatter.dateFormat = "E"
let todaysDate = formatter.string(from: today)
return todaysDate
}
}
CodePudding user response:
Structs are value type, you modify the (copied) item in the filtered array but not the original item in the itemViewModel
object.
A possible solution is to get the item in the itemViewModel
object by id
and modify that directly.
.onChange(of: currentIndex) { value in
let id = tempList[value].id
let index = itemViewModel.list.firstIndex{$0.id == id}!
itemViewModel.list[index].viewedThisItem()
}
Force unwrapping is safe because the item does exist.