Skip to content

Commit

Permalink
Fix negative values counted for the modals
Browse files Browse the repository at this point in the history
  • Loading branch information
tboba committed Oct 13, 2023
1 parent e910699 commit b0243c7
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 4 deletions.
45 changes: 42 additions & 3 deletions ios/RNSScreen.mm
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,13 @@ - (void)setStatusBarHidden:(BOOL)statusBarHidden
_statusBarHidden = statusBarHidden;
[RNSScreenWindowTraits assertViewControllerBasedStatusBarAppearenceSet];
[RNSScreenWindowTraits updateStatusBarAppearance];

// As the status bar could change its visibility, we need to calculate header
// height for the correct value in `onHeaderHeightChange` event when navigation
// bar is not visible.
if (self.controller.navigationController.navigationBarHidden) {
[self.controller calculateAndNotifyHeaderHeightChangeIsModal:NO];
}
}

- (void)setScreenOrientation:(UIInterfaceOrientationMask)screenOrientation
Expand Down Expand Up @@ -1058,6 +1065,30 @@ - (BOOL)hasNestedStack
return NO;
}

- (CGSize)getStatusBarHeightIsModal:(BOOL)isModal
{
#if !TARGET_OS_TV
CGSize fallbackStatusBarSize = [[UIApplication sharedApplication] statusBarFrame].size;

#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_13_0) && \
__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0
if (@available(iOS 13.0, *)) {
CGSize primaryStatusBarSize = self.view.window.windowScene.statusBarManager.statusBarFrame.size;
if (primaryStatusBarSize.height == 0 || primaryStatusBarSize.width == 0)
return fallbackStatusBarSize;

return primaryStatusBarSize;
} else {
return fallbackStatusBarSize;
}
#endif /* Check for iOS 13.0 */

#else
// TVOS does not have status bar.
return CGSizeMake(0, 0);
#endif // !TARGET_OS_TV
}

- (UINavigationController *)getVisibleNavigationControllerIsModal:(BOOL)isModal
{
UINavigationController *navctr = self.navigationController;
Expand All @@ -1081,9 +1112,17 @@ - (UINavigationController *)getVisibleNavigationControllerIsModal:(BOOL)isModal
- (CGFloat)calculateHeaderHeightIsModal:(BOOL)isModal
{
UINavigationController *navctr = [self getVisibleNavigationControllerIsModal:isModal];

if (navctr == nil || navctr.navigationBarHidden) {
return 0;
CGSize statusBarSize = [self getStatusBarHeightIsModal:isModal];

// If navigation controller doesn't exists (or it is hidden) we want to handle two possible cases.
// If there's no navigation controller for the modal, we simply don't want to return header height, as modal possibly
// does not have header and we don't want to count status bar. If there's no navigation controller for the view we
// just want to return status bar height (if it's hidden, it will simply return 0).
if (navctr == nil || navctr.isNavigationBarHidden) {
if (isModal)
return 0;
else
return MIN(statusBarSize.width, statusBarSize.height);
}

CGFloat navbarHeight = navctr.navigationBar.frame.size.height;
Expand Down
2 changes: 1 addition & 1 deletion src/native-stack/views/NativeStackView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ const RouteView = ({
// We need to ensure the first retrieved header height will be cached and set in animatedHeaderHeight.
// We're caching the header height here, as on iOS native side events are not always coming to the JS on first notify.
// TODO: Check why first event is not being received once it is cached on the native side.
const cachedAnimatedHeaderHeight = React.useRef(statusBarHeight);
const cachedAnimatedHeaderHeight = React.useRef(defaultHeaderHeight);
const animatedHeaderHeight = React.useRef(
new Animated.Value(staticHeaderHeight, {
useNativeDriver: true,
Expand Down

0 comments on commit b0243c7

Please sign in to comment.