Closed kyleve closed 1 year ago
Do you happen to have a vanilla UICollectionView repro of this problem? I can file a feedback with Apple if you haven't already.
I haven't, I couldn't repro in Flow layout which makes me think its either doing something similarly special, or I didn't quite poke things right.
The below works around a (seeming?) bug or odd behavior in
UICollectionView
, where it tries to be smart about recycling supplementary views that contain a first responder such as a text field. Specifically, it holds onto a supplementary view that contains a first responder, not immediately recycling it when it is scrolled out of view. That ensures that the keyboard isn't immediately dismissed, which would be jarring....Unfortunately, this doesn't seem to actually work in practice very well. When the supplementary view is scrolled back into view, and we're asked to dequeue a view, the collection view hands us back a different view, leading to double views that get stacked on top of each other in the layout, leading to a bunch of weirdness.
So, to work around this, we do a few things:
1) We begin tracking which supplementary views currently contain a first responder. For practicality of implementation, we only track text fields right now. This could change, but is harder, given there's no generic "first responder changed" notification. This code lives in
ListView
.2) We update
ListLayoutContent.content(in: ...)
to always return supplementary info when a supplementary view contains a first responder, even when out of frame. This ensures the supplementary view instance is kept alive by the collection view. You can see that happening here:3) Within
collectionView(_:viewForSupplementaryElementOfKind:at:)
, we check to see if there's a live, existingvisibleContainer
(aka the supplementary view) view, and if there is, we return that, instead of just dequeuing a new, wrong view.After all that, the correct thing happens.
Checklist
Please do the following before merging:
Main
section.