From f169f362170f71f713757eb57da0fe7428f315b1 Mon Sep 17 00:00:00 2001 From: Mark de Vocht Date: Wed, 25 Mar 2026 15:49:43 +0200 Subject: [PATCH] Navigation.showOverlay() breaks VoiceOver accessibility - background content remains accessible --- ios/RNNCommandsHandler.mm | 52 ++++++++++++++++++++++----------------- ios/RNNOverlayManager.mm | 2 ++ 2 files changed, 31 insertions(+), 23 deletions(-) diff --git a/ios/RNNCommandsHandler.mm b/ios/RNNCommandsHandler.mm index 117977935a2..9b14fcfde92 100644 --- a/ios/RNNCommandsHandler.mm +++ b/ios/RNNCommandsHandler.mm @@ -118,14 +118,18 @@ - (void)mergeOptions:(NSString *)componentId UIViewController *vc = [_layoutManager findComponentForId:componentId]; RNNNavigationOptions *newOptions = [[RNNNavigationOptions alloc] initWithDict:mergeOptions]; - if ([vc conformsToProtocol:@protocol(RNNLayoutProtocol)] || - [vc isKindOfClass:[RNNComponentViewController class]]) { + if (vc && ([vc conformsToProtocol:@protocol(RNNLayoutProtocol)] || + [vc isKindOfClass:[RNNComponentViewController class]])) { [CATransaction begin]; [CATransaction setCompletionBlock:completion]; [vc mergeOptions:newOptions]; [CATransaction commit]; + } else { + if (completion) { + completion(); + } } } @@ -324,10 +328,10 @@ - (void)popTo:(NSString *)componentId RNNComponentViewController *vc = (RNNComponentViewController *)[_layoutManager findComponentForId:componentId]; - RNNNavigationOptions *options = [[RNNNavigationOptions alloc] initWithDict:mergeOptions]; - [vc mergeOptions:options]; - if (vc) { + RNNNavigationOptions *options = [[RNNNavigationOptions alloc] initWithDict:mergeOptions]; + [vc mergeOptions:options]; + [vc.stack popTo:vc animated:[vc.resolveOptionsWithDefault.animations.pop.enable withDefault:YES] completion:^(NSArray *poppedViewControllers) { @@ -355,25 +359,27 @@ - (void)popToRoot:(NSString *)componentId RNNComponentViewController *vc = (RNNComponentViewController *)[_layoutManager findComponentForId:componentId]; - RNNNavigationOptions *options = [[RNNNavigationOptions alloc] initWithDict:mergeOptions]; - [vc mergeOptions:options]; - - [CATransaction begin]; - [CATransaction setCompletionBlock:^{ - [self->_eventEmitter sendOnNavigationCommandCompletion:popToRoot commandId:commandId]; - completion(); - }]; - - [vc.stack popToRoot:vc - animated:[vc.resolveOptionsWithDefault.animations.pop.enable withDefault:YES] - completion:^(NSArray *poppedViewControllers) { - - } - rejection:^(NSString *code, NSString *message, NSError *error){ - - }]; + if (vc) { + RNNNavigationOptions *options = [[RNNNavigationOptions alloc] initWithDict:mergeOptions]; + [vc mergeOptions:options]; - [CATransaction commit]; + [vc.stack popToRoot:vc + animated:[vc.resolveOptionsWithDefault.animations.pop.enable withDefault:YES] + completion:^(NSArray *poppedViewControllers) { + [self->_eventEmitter sendOnNavigationCommandCompletion:popToRoot + commandId:commandId]; + completion(); + } + rejection:rejection]; + } else { + [RNNErrorHandler + reject:rejection + withErrorCode:1012 + errorDescription: + [NSString stringWithFormat: + @"PopToRoot component failed - componentId '%@' not found", + componentId]]; + } } - (void)showModal:(NSDictionary *)layout diff --git a/ios/RNNOverlayManager.mm b/ios/RNNOverlayManager.mm index 72247484651..f0c336ec948 100644 --- a/ios/RNNOverlayManager.mm +++ b/ios/RNNOverlayManager.mm @@ -19,6 +19,7 @@ - (void)showOverlayWindow:(RNNOverlayWindow *)overlayWindow { [overlayWindow setHidden:NO]; overlayWindow.previousWindow.accessibilityElementsHidden = YES; + UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, overlayWindow); } - (void)showOverlayWindowAsKeyWindow:(RNNOverlayWindow *)overlayWindow { @@ -41,6 +42,7 @@ - (void)dismissAllOverlays { - (void)detachOverlayWindow:(RNNOverlayWindow *)overlayWindow { overlayWindow.previousWindow.accessibilityElementsHidden = NO; + UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, nil); [overlayWindow.previousWindow makeKeyWindow]; [overlayWindow setHidden:YES];