- Remove explicit "self."
- Add comment going into detail about the UIKit behavior we're working
around
- Remove force-unwrap from assert. It's safe, but eyebrow raising
Also fixed a minor bug I found:
percentOfIndexPathVisibleAboveBottom is explicitly checking "above the
bottom". Rect intersection is pretty, but if a single cell extended
above the top and bottom margins it would return an incorrect value.
I'm not sure if this is possible, but it's still incorrect.
Instead, this mostly reverts to the original behavior, comparing the top
of the cell frame with the bottom of the content frame. It leverages the
new function to compute the visibleContentRect to do so.
This fixes a bug where the ScrollDownButton would continue to persist
even after jumping to the bottom.
This is due to undefined ordering in UIKit with how it handles
scrollViewDidScroll: and updating the collectionView's visible index
paths. We'd receive the final scrollViewDidScroll: before the visible
items were updated.
To fix this, we need to figure out what cell's are visible without
relying on UICollectionView's cell appearance to be up to date. This
instead uses the collection view layout's cell frames to determine if
they live in the visible content rect of the collection view. Since
layout must be available for the cell to be visible, this should be
correct.
Made some other minor changes around naming. Clarified that lastSortId
and lastIndexPath refer to the viewmodel's loaded window, not the
global thread state.
Our target index path should be determined after updating the
ConversationViewModel's window.
A more robust solution might involve pinning the bottom page to *always*
be loaded in the ConversationViewModel. But for now, this should fix the
assertion.
The image picker was not quite dismissing a view but rather it was
restoring it to fill the screen's frame by updating the offset. This
change updates the frame.origin.y of the collection view's frame to
account for the height of the view's height. This gives us an animation
that pushes the view off-screen as we'd expect before the controller
removes the view altogether.