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

[WIP] Add safeAreaInsets to the Dimensions module #19921

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Libraries/Utilities/Dimensions.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class Dimensions {
eventEmitter.emit('change', {
window: dimensions.window,
screen: dimensions.screen,
safeAreaInsets: dimensions.safeAreaInsets,
});
} else {
dimensionsInitialized = true;
Expand Down
9 changes: 8 additions & 1 deletion React/Modules/RCTDeviceInfo.m
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,16 @@ static BOOL RCTIsIPhoneX() {
@"scale": @(window.scale),
@"fontScale": @(window.fontScale)
};
NSDictionary<NSString *, NSNumber *> *safeAreaInsets = @{
@"left": @(dimensions.safeAreaInsets.left),
@"top": @(dimensions.safeAreaInsets.top),
@"right": @(dimensions.safeAreaInsets.right),
@"bottom": @(dimensions.safeAreaInsets.bottom),
};
return @{
@"window": dims,
@"screen": dims
@"screen": dims,
@"safeAreaInsets": safeAreaInsets,
};
}

Expand Down
3 changes: 3 additions & 0 deletions React/UIUtils/RCTUIUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ typedef struct {
struct {
CGFloat width, height, scale, fontScale;
} window, screen;
struct {
CGFloat left, top, right, bottom;
} safeAreaInsets;
} RCTDimensions;
extern __attribute__((visibility("default")))
RCTDimensions RCTGetDimensions(CGFloat fontScale);
Expand Down
18 changes: 18 additions & 0 deletions React/UIUtils/RCTUIUtils.m
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Copy link
Contributor

@patrickkempff patrickkempff Jun 27, 2018

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.

Copy link
Contributor Author

@janicduplessis janicduplessis Jun 27, 2018

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.

Copy link
Contributor

@patrickkempff patrickkempff Jun 27, 2018

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!

Copy link
Contributor Author

@janicduplessis janicduplessis Jun 27, 2018

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.

Copy link

@burkeshartsis burkeshartsis Oct 16, 2018

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

typeof (result.safeAreaInsets) safeAreaInsets = {
.left = windowInsets.left,
.top = windowInsets.top,
.right = windowInsets.right,
.bottom = windowInsets.bottom
};
result.safeAreaInsets = safeAreaInsets;
} else {
// Polyfill `safeAreaInsets` for iOS < 11. We only care about the status bar.
typeof (result.safeAreaInsets) safeAreaInsets = {
// TODO: Test this with in-call status bar.
.top = RCTSharedApplication().statusBarFrame.size.height
};
result.safeAreaInsets = safeAreaInsets;
}

return result;
}

Expand Down