Skip to content
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

RCTRefreshControl: Updates progressOffset behaviour to prevent it from being applied by default #35281

Closed

Conversation

objectivecosta
Copy link
Contributor

@objectivecosta objectivecosta commented Nov 9, 2022

Summary

UIRefreshControl has a tight integration with iOS in terms of UINavigationBar/UIScrollView. In this regard, whenever there's a UIScrollView with a UINavigationBar on top, the OS automatically adjusts the contentInset of the UIScrollView to reflect that (something that is exposed to React Native). In a similar manner, UIScrollView passes this along to the attached UIRefreshControl.

By setting the frame manually, the RCTRefreshControl component was preventing this behavior. Although having the option is desired, it should not be done by default. In the past it was possible to adjust for this by manually setting the correct value, calculating the statusBar's height/safeAreaInsets.top and appending 44pt (the UINavigationBar height). However, due to changes related to the Dynamic Island (see here), the safe area and the status bar size no longer align, making this calculation more tricky.

In summary: this changes allows progressViewOffset to exist (in order to maintain feature parity with Android) but provides the opportunity for the OSs default behavior to kick in when applicable.

Applying by default Not applying by default (this change)

Changelog

[iOS] [Fixed] - Fix application of _progressViewOffset in RCTRefreshControl to not occur by default (when value is unset)

Test Plan

The GIFs attached display the behavior as expected/unexpected. I'm unaware of any tests written for RCTRefreshControl that could be improved to cover this change. Notes appreciated.

@analysis-bot
Copy link

analysis-bot commented Nov 9, 2022

Platform Engine Arch Size (bytes) Diff
android hermes arm64-v8a 7,070,062 -29,214
android hermes armeabi-v7a 6,442,430 -26,503
android hermes x86 7,485,469 -31,663
android hermes x86_64 7,344,931 -30,860
android jsc arm64-v8a 8,934,550 -29,373
android jsc armeabi-v7a 7,668,661 -26,649
android jsc x86 8,994,599 -31,816
android jsc x86_64 9,473,532 -31,022

Base commit: b8893c7
Branch: main

@facebook-github-bot
Copy link
Contributor

Hi @objectivecosta!

Thank you for your pull request and welcome to our community.

Action Required

In order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you.

Process

In order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA.

Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with CLA signed. The tagging process may take up to 1 hour after signing. Please give it that time before contacting us about it.

If you have received this in error or have any questions, please contact us at cla@meta.com. Thanks!

@analysis-bot
Copy link

analysis-bot commented Nov 9, 2022

Platform Engine Arch Size (bytes) Diff
ios - universal n/a --

Base commit: b8893c7
Branch: main

@pull-bot
Copy link

pull-bot commented Nov 9, 2022

PR build artifact for 4438584 is ready.
To use, download tarball from "Artifacts" tab in this CircleCI job then run yarn add <path to tarball> in your React Native project.

@pull-bot
Copy link

pull-bot commented Nov 9, 2022

PR build artifact for 4438584 is ready.
To use, download tarball from "Artifacts" tab in this CircleCI job then run yarn add <path to tarball> in your React Native project.

@facebook-github-bot
Copy link
Contributor

Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks!

@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Nov 9, 2022
@facebook-github-bot
Copy link
Contributor

Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks!

@objectivecosta
Copy link
Contributor Author

Can't seem to request a review via the GitHub UI as usual, pinging @cipolleschi instead ;)

@objectivecosta
Copy link
Contributor Author

One thing that I reflected upon is that maybe the condition can be changed for != 0.f instead of > 0.f, to allow for negative offsets. Is that a possible scenario?

RCTRefreshControl: Updates condition for applying offset to be `!= 0.f`, not `> 0.f`. This will allow negative offsets, if needed.
@objectivecosta
Copy link
Contributor Author

Updated the condition to be != 0.f, to allow for negative offsets. PR is ready for review, but I don't know how to request one here :/

Copy link
Contributor

@cipolleschi cipolleschi left a comment

Choose a reason for hiding this comment

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

Hi @objectivecosta, thank you so much for doing this, that's great.

I added a comment to improve the readability of the code, but it is a personal preference (coming from Swift and guard statements) so feel free to disregard it if you don't feel like it.

I'll also look into why you couldn't request a review, but it's fine to ping me (hoping I don't miss the notification! 😅)

// Setting the UIRefreshControl's frame breaks integration with ContentInset from the superview
// if it is a UIScrollView. This integration happens when setting the UIScrollView's .refreshControl
// property. For this reason, setting the frame manually should be avoided, if not needed.
if (_progressViewOffset != 0.f) {
Copy link
Contributor

Choose a reason for hiding this comment

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

What about an early return? Something like:

if (_progressViewOffset == 0.f) {
  return
}

It limits the indentation of the code and the positive check make it immediately clear that if the offset is 0 we don't want to do anything.

What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Makes total sense @cipolleschi! Changed it ;)

@facebook-github-bot
Copy link
Contributor

@cipolleschi has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

@pull-bot
Copy link

PR build artifact for c035025 is ready.
To use, download tarball from "Artifacts" tab in this CircleCI job then run yarn add <path to tarball> in your React Native project.

@pull-bot
Copy link

PR build artifact for c035025 is ready.
To use, download tarball from "Artifacts" tab in this CircleCI job then run yarn add <path to tarball> in your React Native project.

Updates _applyProgressViewOffset with an early return for readability
@facebook-github-bot
Copy link
Contributor

@cipolleschi has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

@pull-bot
Copy link

PR build artifact for bf24c9f is ready.
To use, download tarball from "Artifacts" tab in this CircleCI job then run yarn add <path to tarball> in your React Native project.

@pull-bot
Copy link

PR build artifact for bf24c9f is ready.
To use, download tarball from "Artifacts" tab in this CircleCI job then run yarn add <path to tarball> in your React Native project.

@objectivecosta
Copy link
Contributor Author

ping @cipolleschi: I think this is ready for merging!

@cipolleschi
Copy link
Contributor

It has landed! 0062b10

@objectivecosta
Copy link
Contributor Author

Great stuff! Thanks @cipolleschi :D

OlimpiaZurek pushed a commit to OlimpiaZurek/react-native that referenced this pull request May 22, 2023
…m being applied by default (facebook#35281)

Summary:
UIRefreshControl has a tight integration with iOS in terms of UINavigationBar/UIScrollView. In this regard, whenever there's a UIScrollView with a UINavigationBar on top, the OS automatically adjusts the contentInset of the UIScrollView to reflect that (something that is exposed to React Native). In a similar manner, UIScrollView passes this along to the attached UIRefreshControl.

By setting the frame manually, the RCTRefreshControl component was preventing this behavior. Although having the option is desired, it should not be done by default. In the past it was possible to adjust for this by manually setting the correct value, calculating the statusBar's height/safeAreaInsets.top and appending 44pt (the UINavigationBar height). However, due to changes related to the Dynamic Island (see [here](https://useyourloaf.com/blog/iphone-14-screen-sizes)), the safe area and the status bar size no longer align, making this calculation more tricky.

In summary: this changes allows `progressViewOffset` to exist (in order to maintain feature parity with Android) but provides the opportunity for the OSs default behavior to kick in when applicable.

| Applying by default  | Not applying by default (this change) |
:-------------------------:|:-------------------------:
![](https://user-images.githubusercontent.com/753361/200828632-0c9aa605-770c-47be-a825-1e061478c2b4.gif)  |  ![](https://user-images.githubusercontent.com/753361/200828664-dded9a47-bdbc-4b88-8ab7-92a76cea47e8.gif)

## Changelog

<!-- Help reviewers and the release process by writing your own changelog entry. For an example, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests
-->

[iOS] [Fixed] - Fix application of _progressViewOffset in RCTRefreshControl to not occur by default (when value is unset)

Pull Request resolved: facebook#35281

Test Plan: The GIFs attached display the behavior as expected/unexpected. I'm unaware of any tests written for RCTRefreshControl that could be improved to cover this change. Notes appreciated.

Reviewed By: sammy-SC

Differential Revision: D41302080

Pulled By: cipolleschi

fbshipit-source-id: a2a8e6ef1dcc2e73220c2a182b4516f3bbd94f60
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Platform: iOS iOS applications.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants