fix(ios): keep a zoomed ScrollView usable when its content size changes - #58498
Open
mifi wants to merge 1 commit into
Open
fix(ios): keep a zoomed ScrollView usable when its content size changes#58498mifi wants to merge 1 commit into
mifi wants to merge 1 commit into
Conversation
`RCTScrollViewComponentView`'s `_containerView` is also the view that UIScrollView zooms (`viewForZoomingInScrollView:`), so while the user is pinch-zoomed in it carries a scale transform. On every content size change `updateState:oldState:` assigned `_containerView.frame`, which is undefined behavior for a view with a non-identity transform (UIKit ends up shrinking the view's bounds by the zoom scale), and it also passed the unzoomed size to the UIScrollView as `contentSize`. The visible result: pinch-zoom into a ScrollView, then change its size (rotate the device, or change the layout around it). The scrolled position jumps, and the content can no longer be zoomed all the way out; it stays stuck in a corner until the user zooms out and resizes again. Lay the container out through `bounds` and `center` instead, and give the scroll view the zoomed content size, which is what UIScrollView itself keeps `contentSize` at while zooming.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary:
RCTScrollViewComponentView's_containerViewis also the view UIScrollView zooms (viewForZoomingInScrollView:), so while the user is pinch-zoomed in it carries a scale transform. On every content size changeupdateState:oldState:assigned_containerView.frame, which is undefined behavior for a view with a non-identity transform (in practice UIKit shrinks the view's bounds by the zoom scale), and it also handed the unzoomed size to the UIScrollView ascontentSize.Visible result: pinch-zoom into a ScrollView, then change its size (rotate the device, or change the layout around it). The scrolled position jumps, and the content can no longer be zoomed all the way out; it stays stuck in a corner until the user zooms out and resizes again.
This lays the container out through
boundsandcenterinstead, and gives the scroll view the zoomed content size, which is what UIScrollView itself keepscontentSizeat while zooming. WithzoomScale == 1the result is identical to before. In RTL, where the container carries a flip transform,bounds/centerproduce the same frame the old assignment did.Changelog:
[IOS] [FIXED] - Pinch-zoomed ScrollView no longer breaks (position jump, cannot zoom back out) when its size changes
Test Plan:
Generated by Claude Code