Skip to content

Fix supplementary view + contained first responder reuse issue #507

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Sep 20, 2023

Conversation

kyleve
Copy link
Collaborator

@kyleve kyleve commented Sep 19, 2023

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:

image
  1. Within collectionView(_:viewForSupplementaryElementOfKind:at:), we check to see if there's a live, existing visibleContainer (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:

  • Ensure any public-facing changes are reflected in the changelog. Include them in the Main section.

@kyleve kyleve changed the title [WIP DNR] Initial commit: Fix supplementary view reuse issue Fix supplementary view + contained first responder reuse issue Sep 20, 2023
@kyleve kyleve marked this pull request as ready for review September 20, 2023 17:22
@kyleve kyleve requested a review from a team September 20, 2023 17:23
Copy link
Member

@robmaceachern robmaceachern left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

Do you happen to have a vanilla UICollectionView repro of this problem? I can file a feedback with Apple if you haven't already.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

If we really need to, we can try out the UIWindowFirstResponderDidChangeNotification private api. I think scoping to text fields is totally fine though.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

of course it's from Peter Steinberger

@kyleve
Copy link
Collaborator Author

kyleve commented Sep 20, 2023

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.

@kyleve kyleve merged commit df73699 into main Sep 20, 2023
@kyleve kyleve deleted the kve/fix-supplementary-first-responder-issue branch September 20, 2023 21:49
kyleve added a commit that referenced this pull request Nov 19, 2023
…rovements

* origin/main: (123 commits)
  Update CHANGELOG.md (#508)
  Revert "Supplementary Tracking Fixes (#433)"
  Revert "Force layout before appear, to avoid animated updates (#505)"
  Force layout before appear, to avoid animated updates (#505)
  Update workaround versions (#506)
  Fix supplementary view + contained first responder reuse issue (#507)
  Supplementary Tracking Fixes (#433)
  Release 13.0.0 (#504)
  Update KeyboardObserver (#499)
  CONV-1435: Gravity layout frame change fix - Before: Layout gravity doesn't take into account frame changes. For example, when the orientation changes the scroll position (relative to the bottom) changes - After: Layout gravity takes frame changes into account so the when the frame changes the scroll position relative to the bottom remains unchanged
  Release 12.0.0 (#501)
  CONV-1435: Add scroll indicator insets to customScrollViewInsets (#500)
  CONV-1435: Gravity layout - Adds a new Chat App demo and a new behavior called verticalLayoutGravity.  When verticalLayoutGravity is set to bottom, scrolling works the way you would expect for a messaging app.
  expose onKeyboardFrameWillChange on ListProperties
  onKeyboardFrameWillChange: Improve CHANGELOG, DocC
  CONV-1435: Custom keyboard adjustment mode - Adds a .custom KeyboardAdjustmentMode to fully customize inset behavior
  remove contentOffset from isContentScrollable calculation, improve comment
  Add ListView#isContentScrollable property - Add this property to ListView. It will be used in conjunction with upcoming so-called gravity scrolling changes to workaround an animation issue with paging
  Update CI script to reference the `xcodesorg/made/xcodes` package for installing simulator runtimes. (#494)
  Swipe Action Updates (#489)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants