diff --git a/ios/RNSScreenContentWrapper.mm b/ios/RNSScreenContentWrapper.mm index dcb87f2fb..68558e9a9 100644 --- a/ios/RNSScreenContentWrapper.mm +++ b/ios/RNSScreenContentWrapper.mm @@ -73,15 +73,30 @@ - (void)attachToAncestorScreenViewStartingFrom:(nonnull RNSScreen *)screenCtrl - (void)attachToAncestorScreenView { - if (![self.reactSuperview isKindOfClass:RNSScreenView.class]) { - RCTLogError(@"Expected reactSuperview to be a RNSScreenView. Found %@", self.reactSuperview); + RNSScreen *_Nullable screen = + static_cast([[self findFirstScreenViewAncestor] reactViewController]); + if (screen == nil) { + RCTLogError(@"Failed to find parent screen controller from %@.", self); return; } - - RNSScreen *screen = (RNSScreen *)[self.reactSuperview reactViewController]; [self attachToAncestorScreenViewStartingFrom:screen]; } +- (nullable RNSScreenView *)findFirstScreenViewAncestor +{ + UIView *currentView = self; + + // In standard scenario this should do only a single iteration. + // Haven't got repro, but we got reports that there are scenarios + // when there are intermediate views between screen view & the content wrapper. + // https://github.com/software-mansion/react-native-screens/pull/2683 + do { + currentView = currentView.reactSuperview; + } while (currentView != nil && ![currentView isKindOfClass:RNSScreenView.class]); + + return static_cast(currentView); +} + #ifdef RCT_NEW_ARCH_ENABLED #pragma mark - RCTComponentViewProtocol