admin管理员组文章数量:1316561
I want to show progress in collection view cell text label. I use this code to do it. Code from observer works and I see print progress in debug but I can't see this in cell. Why?
KVO variant (not working)
I get progress inside the observer, but the cell text is not updated. Why?
var nameObservation: NSKeyValueObservation?
@objc dynamic var progress = 0.0
func createDataSource() {
dataSource = UICollectionViewDiffableDataSource<Section, Item>(collectionView: collectionView) { collectionView, indexPath, item in
switch self.sections[indexPath.section].identifier {
case "carouselCell":
let cell = self.configure(CarouselCell.self, with: item, for: indexPath)
self.nameObservation = self.observe(\.progress, options: .new) { vc, change in
cell.title.text = "\(self.progress)"
}
return cell
default: return self.configure(CarouselCell.self, with: item, for: indexPath)
}
}
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
_ = Timer.scheduledTimer(withTimeInterval: 0.10, repeats: true) { timer in
guard self.progress <= 1.0 else {
timer.invalidate()
self.progress = 0.0
return
}
}
}
Notification variant (not working).
I'm also trying to solve this problem using notifications. And my collection disappears after clicking
var nameObservation: NSKeyValueObservation?
@objc func createDataSource() {
dataSource = UICollectionViewDiffableDataSource<Section, Item>(collectionView: collectionView) { collectionView, indexPath, item in
switch self.sections[indexPath.section].identifier {
case "carouselCell":
let cell = self.configure(CarouselCell.self, with: item, for: indexPath)
cell.title.text = "\(self.progressA)"
print(self.progressA)
return cell
default: return self.configure(CarouselCell.self, with: item, for: indexPath)
}
}
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
NotificationCenter.default.addObserver(
self, selector: #selector(self.createDataSource),
name: Notification.Name(rawValue: "sound-CarouselController"), object: nil)
_ = Timer.scheduledTimer(withTimeInterval: 0.10, repeats: true) { timer in
guard self.progressA <= 1.0 else {
timer.invalidate()
self.progressA = 0.0
return
}
self.progressA += 0.01
NotificationCenter.default.post(name: Notification.Name(rawValue: "sound-CarouselController"), object: nil)
}
}
I want to show progress in collection view cell text label. I use this code to do it. Code from observer works and I see print progress in debug but I can't see this in cell. Why?
KVO variant (not working)
I get progress inside the observer, but the cell text is not updated. Why?
var nameObservation: NSKeyValueObservation?
@objc dynamic var progress = 0.0
func createDataSource() {
dataSource = UICollectionViewDiffableDataSource<Section, Item>(collectionView: collectionView) { collectionView, indexPath, item in
switch self.sections[indexPath.section].identifier {
case "carouselCell":
let cell = self.configure(CarouselCell.self, with: item, for: indexPath)
self.nameObservation = self.observe(\.progress, options: .new) { vc, change in
cell.title.text = "\(self.progress)"
}
return cell
default: return self.configure(CarouselCell.self, with: item, for: indexPath)
}
}
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
_ = Timer.scheduledTimer(withTimeInterval: 0.10, repeats: true) { timer in
guard self.progress <= 1.0 else {
timer.invalidate()
self.progress = 0.0
return
}
}
}
Notification variant (not working).
I'm also trying to solve this problem using notifications. And my collection disappears after clicking
var nameObservation: NSKeyValueObservation?
@objc func createDataSource() {
dataSource = UICollectionViewDiffableDataSource<Section, Item>(collectionView: collectionView) { collectionView, indexPath, item in
switch self.sections[indexPath.section].identifier {
case "carouselCell":
let cell = self.configure(CarouselCell.self, with: item, for: indexPath)
cell.title.text = "\(self.progressA)"
print(self.progressA)
return cell
default: return self.configure(CarouselCell.self, with: item, for: indexPath)
}
}
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
NotificationCenter.default.addObserver(
self, selector: #selector(self.createDataSource),
name: Notification.Name(rawValue: "sound-CarouselController"), object: nil)
_ = Timer.scheduledTimer(withTimeInterval: 0.10, repeats: true) { timer in
guard self.progressA <= 1.0 else {
timer.invalidate()
self.progressA = 0.0
return
}
self.progressA += 0.01
NotificationCenter.default.post(name: Notification.Name(rawValue: "sound-CarouselController"), object: nil)
}
}
Share
Improve this question
edited Jan 30 at 15:54
User
asked Jan 30 at 12:01
UserUser
1951 gold badge1 silver badge11 bronze badges
3
- You have to update the DATA SOURCE, not the cell itself. its very hard to do! – Fattie Commented Jan 30 at 12:37
- @Fattie Please check this answer stackoverflow/a/79398905/6818660 on my previous question. I tried updating the DATA SOURCE in the previous question, but it caused problems. And @Rob recommended that I do what I am trying to do in the current question. Also the current question is not a duplicate of the previous one – User Commented Jan 30 at 12:50
- 1 PS I did not mark your question as a dupe, and I upvoted it! TBH I am not able to look through all the code. I fear that you have some basic problems in the nature of the cells / data source. Updating cells with live animation is really tricky! – Fattie Commented Jan 30 at 15:32
1 Answer
Reset to default 1I find it extremely challenging to animate things in cells, syncing them and so on.
You can see some old QA about it. https://stackoverflow/a/58239612/294884 Synchronise all animations on collection-view cells etc - no idea what's going on in those.
the only honest-to-God solution we have ever found
Make a singleton that entirely handles all your timer(s), progress etc.
So for example there might be some "progress", lets say it is "progress of download 7B" ...
During any frame, anyone at all who wants to, can, get that current value, from the singleton
And that's it. In your cells (or anywhere whatsoever) just draw the value in question (whether a bar or whatever it is) each frame to the value you read from the singleton
So you just completely fet about the madness of UIKit's various animation paradigms.
Just use CADisplayLink and draw everything as you wish - based only on the values in one central singleton.
Don't fet that (of course) cells are constantly changing as you scroll. ie the cell that the user thinks of as "cell 91" is of course displayed by DIFFERENT changing cells as you scroll up and down, hopefully you completely understand this basic paradigm of how recycler views work.
Note that you don't have to bother with the insanity of notifications, subscriptions etc.
It's one of those things that is much, much easier once you make the jump to using normal frame based drawing (CADisplayLink).
When you're testing this you can put the animation anywhere at all, on a normal view, in a popup, in an alert, in cells, in tab bars, whatever. The "cell problems" become nonexistent.
本文标签: iosHow to update collection view with KVOStack Overflow
版权声明:本文标题:ios - How to update collection view with KVO? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741967562a2407638.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论