diff --git a/shell/platform/darwin/ios/framework/Source/accessibility_bridge.h b/shell/platform/darwin/ios/framework/Source/accessibility_bridge.h index f563b73ce266a..aaba31842c9e5 100644 --- a/shell/platform/darwin/ios/framework/Source/accessibility_bridge.h +++ b/shell/platform/darwin/ios/framework/Source/accessibility_bridge.h @@ -32,7 +32,7 @@ class AccessibilityBridge; /** * A node in the iOS semantics tree. */ -@interface SemanticsObject : NSObject +@interface SemanticsObject : UIAccessibilityElement /** * The globally unique identifier for this node. @@ -126,7 +126,7 @@ class AccessibilityBridge; * * `SemanticsObject` for the other type of semantics objects. * * `FlutterSemanticsObject` for default implementation of `SemanticsObject`. */ -@interface FlutterPlatformViewSemanticsContainer : NSObject +@interface FlutterPlatformViewSemanticsContainer : UIAccessibilityElement /** * The position inside an accessibility container. diff --git a/shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm b/shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm index 938cec276ac37..36f320d93856e 100644 --- a/shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm +++ b/shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm @@ -81,7 +81,7 @@ @implementation FlutterCustomAccessibilityAction { * there for structure and they don't provide any semantic information to VoiceOver (they return * NO for isAccessibilityElement). */ -@interface SemanticsObjectContainer : NSObject +@interface SemanticsObjectContainer : UIAccessibilityElement - (instancetype)init __attribute__((unavailable("Use initWithSemanticsObject instead"))); - (instancetype)initWithSemanticsObject:(SemanticsObject*)semanticsObject bridge:(fml::WeakPtr)bridge @@ -109,7 +109,11 @@ - (instancetype)init { - (instancetype)initWithBridge:(fml::WeakPtr)bridge uid:(int32_t)uid { FML_DCHECK(bridge) << "bridge must be set"; FML_DCHECK(uid >= kRootNodeId); - self = [super init]; + // Initialize with the UIView as the container. + // The UIView will not necessarily be accessibility parent for this object. + // The bridge informs the OS of the actual structure via + // `accessibilityContainer` and `accessibilityElementAtIndex`. + self = [super initWithAccessibilityContainer:bridge->view()]; if (self) { _bridge = bridge; @@ -429,7 +433,11 @@ - (instancetype)init { - (instancetype)initWithSemanticsObject:(SemanticsObject*)object { FML_CHECK(object); - if (self = [super init]) { + // Initialize with the UIView as the container. + // The UIView will not necessarily be accessibility parent for this object. + // The bridge informs the OS of the actual structure via + // `accessibilityContainer` and `accessibilityElementAtIndex`. + if (self = [super initWithAccessibilityContainer:object.bridge->view()]) { _semanticsObject = object; flutter::FlutterPlatformViewsController* controller = object.bridge->GetPlatformViewsController(); @@ -476,7 +484,11 @@ - (instancetype)init { - (instancetype)initWithSemanticsObject:(SemanticsObject*)semanticsObject bridge:(fml::WeakPtr)bridge { FML_DCHECK(semanticsObject) << "semanticsObject must be set"; - self = [super init]; + // Initialize with the UIView as the container. + // The UIView will not necessarily be accessibility parent for this object. + // The bridge informs the OS of the actual structure via + // `accessibilityContainer` and `accessibilityElementAtIndex`. + self = [super initWithAccessibilityContainer:bridge->view()]; if (self) { _semanticsObject = semanticsObject;