Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit bbc9bd8

Browse files
author
Chris Yang
authored
iOS: A11y only disable during app resigning to background when voice over on (#32820)
1 parent 2f7c922 commit bbc9bd8

File tree

3 files changed

+44
-1
lines changed

3 files changed

+44
-1
lines changed

shell/platform/darwin/ios/framework/Headers/FlutterViewController.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,14 @@ FLUTTER_DARWIN_EXPORT
179179
*/
180180
- (id<FlutterPluginRegistry>)pluginRegistry;
181181

182+
/**
183+
* A wrapper around UIAccessibilityIsVoiceOverRunning().
184+
*
185+
* As a C function, UIAccessibilityIsVoiceOverRunning() cannot be mocked in testing. Mock
186+
* this class method to testing features depends on UIAccessibilityIsVoiceOverRunning().
187+
*/
188+
+ (BOOL)isUIAccessibilityIsVoiceOverRunning;
189+
182190
/**
183191
* True if at least one frame has rendered and the ViewController has appeared.
184192
*

shell/platform/darwin/ios/framework/Source/FlutterViewController.mm

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -826,7 +826,9 @@ - (void)applicationBecameActive:(NSNotification*)notification {
826826

827827
- (void)applicationWillResignActive:(NSNotification*)notification {
828828
TRACE_EVENT0("flutter", "applicationWillResignActive");
829-
self.view.accessibilityElementsHidden = YES;
829+
if ([FlutterViewController isUIAccessibilityIsVoiceOverRunning]) {
830+
self.view.accessibilityElementsHidden = YES;
831+
}
830832
[self goToApplicationLifecycle:@"AppLifecycleState.inactive"];
831833
}
832834

@@ -1718,6 +1720,10 @@ - (NSString*)lookupKeyForAsset:(NSString*)asset fromPackage:(NSString*)package {
17181720
return _engine;
17191721
}
17201722

1723+
+ (BOOL)isUIAccessibilityIsVoiceOverRunning {
1724+
return UIAccessibilityIsVoiceOverRunning();
1725+
}
1726+
17211727
#pragma mark - FlutterPluginRegistry
17221728

17231729
- (NSObject<FlutterPluginRegistrar>*)registrarForPlugin:(NSString*)pluginKey {

shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -939,6 +939,9 @@ - (void)testHideA11yElements {
939939
FlutterViewController* realVC = [[FlutterViewController alloc] initWithEngine:engine
940940
nibName:nil
941941
bundle:nil];
942+
id flutterViewControllerClassMOCK = OCMClassMock([FlutterViewController class]);
943+
[[[flutterViewControllerClassMOCK stub] andReturnValue:@YES] isUIAccessibilityIsVoiceOverRunning];
944+
942945
XCTAssertFalse(realVC.view.accessibilityElementsHidden);
943946
[[NSNotificationCenter defaultCenter]
944947
postNotificationName:UIApplicationWillResignActiveNotification
@@ -949,6 +952,32 @@ - (void)testHideA11yElements {
949952
object:nil];
950953
XCTAssertFalse(realVC.view.accessibilityElementsHidden);
951954
engine.viewController = nil;
955+
956+
[flutterViewControllerClassMOCK stopMocking];
957+
}
958+
959+
- (void)testDontHideA11yElementsWhenVoiceOverIsOff {
960+
FlutterDartProject* project = [[FlutterDartProject alloc] init];
961+
FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"foobar" project:project];
962+
[engine createShell:@"" libraryURI:@"" initialRoute:nil];
963+
FlutterViewController* realVC = [[FlutterViewController alloc] initWithEngine:engine
964+
nibName:nil
965+
bundle:nil];
966+
id flutterViewControllerClassMOCK = OCMClassMock([FlutterViewController class]);
967+
[[[flutterViewControllerClassMOCK stub] andReturnValue:@NO] isUIAccessibilityIsVoiceOverRunning];
968+
969+
XCTAssertFalse(realVC.view.accessibilityElementsHidden);
970+
[[NSNotificationCenter defaultCenter]
971+
postNotificationName:UIApplicationWillResignActiveNotification
972+
object:nil];
973+
XCTAssertFalse(realVC.view.accessibilityElementsHidden);
974+
[[NSNotificationCenter defaultCenter]
975+
postNotificationName:UIApplicationDidBecomeActiveNotification
976+
object:nil];
977+
XCTAssertFalse(realVC.view.accessibilityElementsHidden);
978+
engine.viewController = nil;
979+
980+
[flutterViewControllerClassMOCK stopMocking];
952981
}
953982

954983
- (void)testNotifyLowMemory {

0 commit comments

Comments
 (0)