-
Notifications
You must be signed in to change notification settings - Fork 24.4k
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
[WIP] Add safeAreaInsets to the Dimensions module #19921
[WIP] Add safeAreaInsets to the Dimensions module #19921
Conversation
@@ -21,6 +21,24 @@ RCTDimensions RCTGetDimensions(CGFloat fontScale) | |||
result.window = dims; | |||
result.screen = dims; | |||
|
|||
if (@available(iOS 11.0, *)) { | |||
UIEdgeInsets windowInsets = RCTKeyWindow().rootViewController.view.safeAreaInsets; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@janicduplessis why aren't you using RCTKeyWindow().safeAreaInsets
? Otherwise it will force the view controller to load the view.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried using that but the insets were always 0.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh that is strange. Just to verify you are not running the code in a app extension right? Because RCTSharedApplication is returning nil when RCTRunningInAppExtension returns true. i need sleep, ofcourse you are not, RCTKeyWindow is returning not nil otherwise it did not work at all.
As an example we are using this is a large scale production app:
- (NSDictionary *) constantsToExport {
return @{
@"SAFE_AREA_INSETS_TOP": @([self safeAreaInsetsTop]),
@"SAFE_AREA_INSETS_BOTTOM": @([self safeAreaInsetsBottom])
};
}
- (CGFloat) safeAreaInsetsTop {
if (@available(iOS 11.0, *)) {
return UIApplication.sharedApplication.keyWindow.safeAreaInsets.top;
}
return 0;
}
- (CGFloat) safeAreaInsetsBottom {
if (@available(iOS 11.0, *)) {
return UIApplication.sharedApplication.keyWindow.safeAreaInsets.bottom;
}
return 0;
}
I wanted to open a PR myself but awesome that you are doing this already. thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Weird, I can try to investigate this further. I agree it would be cleaner to use keyWindow.safeAreaInsets.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For those landing here from Google I believe this is the PR that continued this work. #20999
Android P has support for the "notch" (or other type of insets) as well: getSafeInsetTop()
getSafeInsetBottom()
getSafeInsetLeft()
getSafeInsetRight() https://developer.android.com/reference/android/view/WindowInsets#getDisplayCutout() If you want some help I can join to implement the android side. Let me know! |
@patrickkempff Sure, I planned adding support for Android too but help would be appreciated! If you want you could open a PR on top of this one that adds support for Android. |
Ideally we would also polyfill the notch API to work on older Android versions. It would return the proper top offset when using translucent status bar. Maybe the Android support lib already does that. |
Since you both started working on this API, I would love to get your attention on the Dimension issue I was facing in split mode on both platforms: My investigation is that the underlying mechanism for guessing screen/window dimensions does not respect split mode. |
@janicduplessis I will invest time this weekend into this edit: update, I did investigate the Android API, I have some ideas, not sure yet about the best approach. Any suggestions would be welcome. |
Hi, as you could see here #19627, I used another approach to get safe area insets values on JS side (for iOS only). Don’t know which approach is the best but if it could help... |
@janicduplessis I tried to find reviewers for this pull request and wanted to ping them to take another look. However, based on the blame information for the files in this pull request I couldn't find any reviewers. This sometimes happens when the files in the pull request are new or don't exist on master anymore. Is this pull request still relevant? If yes could you please rebase? In case you know who has context on this code feel free to mention them in a comment (one person is fine). Thanks for reading and hope you will continue contributing to the project. |
@clmntcrl I think the issue with this approach is that you cannot have access to the insets in a synchronous way, before the first render. This could cause some flickers on initial mount. I still think your PR can be useful, I'll have a look soon. |
Closing in favor of #20999 which is a lot less hacky |
@janicduplessis If iPhone X border less design comes to the iPad this year I think using asynchronous approach could be useful to handle safe area insets change due to the use of Split View |
There are some use cases where
SafeAreaView
doesn't work because we need to do some computations or apply the values manually in JS (ex.: margin instead of padding). This exposes the safe area insets of the screen as a new value on theDimensions
module.Kind of depends on #19919
TODO:
Test Plan:
TODO
Release Notes:
[GENERAL] [FEATURE] [Dimensions] - Add safeAreaInsets to the Dimensions module