-
Notifications
You must be signed in to change notification settings - Fork 6k
[ios_platform_view, a11y] Make FlutterPlatformViewSemanticsContainer a SemanticsObject.
#29531
Changes from 1 commit
b97edf9
cbad648
95a0e5b
5329ba5
b9f3fe2
e0b52b8
c5a4ec1
71d825d
b3163cb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -300,7 +300,6 @@ - (void)dealloc { | |
| [_children release]; | ||
| _parent = nil; | ||
| _container.get().semanticsObject = nil; | ||
| [_platformViewSemanticsContainer release]; | ||
| _inDealloc = YES; | ||
| [super dealloc]; | ||
| } | ||
|
|
@@ -319,9 +318,6 @@ - (void)setChildren:(NSArray<SemanticsObject*>*)children { | |
| } | ||
|
|
||
| - (BOOL)hasChildren { | ||
| if (_node.IsPlatformViewNode()) { | ||
| return YES; | ||
| } | ||
| return [self.children count] != 0; | ||
| } | ||
|
|
||
|
|
@@ -753,30 +749,27 @@ - (UIAccessibilityTraits)accessibilityTraits { | |
| @end | ||
|
|
||
| @interface FlutterPlatformViewSemanticsContainer () | ||
| @property(nonatomic, assign) SemanticsObject* semanticsObject; | ||
| @property(nonatomic, strong) UIView* platformView; | ||
| @end | ||
|
|
||
| @implementation FlutterPlatformViewSemanticsContainer | ||
|
|
||
| // Method declared as unavailable in the interface | ||
| - (instancetype)init { | ||
| - (instancetype)initWithBridge:(fml::WeakPtr<flutter::AccessibilityBridgeIos>)bridge | ||
| uid:(int32_t)uid { | ||
| [self release]; | ||
| [super doesNotRecognizeSelector:_cmd]; | ||
| return nil; | ||
| } | ||
|
|
||
| - (instancetype)initWithSemanticsObject:(SemanticsObject*)object { | ||
| FML_CHECK(object); | ||
| // 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; | ||
| auto controller = object.bridge->GetPlatformViewsController(); | ||
| - (instancetype)initWithBridge:(fml::WeakPtr<flutter::AccessibilityBridgeIos>)bridge | ||
| uid:(int32_t)uid | ||
| platformViewId:(int32_t)platformViewId { | ||
| if (self = [super initWithBridge:bridge uid:uid]) { | ||
| auto controller = bridge->GetPlatformViewsController(); | ||
| FML_DCHECK(controller); | ||
| if (controller) { | ||
| _platformView = [controller->GetPlatformViewByID(object.node.platformViewId) retain]; | ||
| _platformView = [controller->GetPlatformViewByID(platformViewId) retain]; | ||
| } | ||
| } | ||
| return self; | ||
|
|
@@ -790,47 +783,8 @@ - (void)dealloc { | |
|
|
||
| #pragma mark - UIAccessibilityContainer overrides | ||
|
|
||
| - (NSInteger)accessibilityElementCount { | ||
| // This container should only contain 2 elements: | ||
| // 1. The semantic object that represents this container. | ||
| // 2. The platform view object. | ||
| return 2; | ||
| } | ||
|
|
||
| - (nullable id)accessibilityElementAtIndex:(NSInteger)index { | ||
| FML_DCHECK(index < 2); | ||
| if (index == 0) { | ||
| return _semanticsObject.nativeAccessibility; | ||
| } else { | ||
| return _platformView; | ||
| } | ||
| } | ||
|
|
||
| - (NSInteger)indexOfAccessibilityElement:(id)element { | ||
| FML_DCHECK(element == _semanticsObject || element == _platformView); | ||
| if (element == _semanticsObject) { | ||
| return 0; | ||
| } else { | ||
| return 1; | ||
| } | ||
| } | ||
|
|
||
| #pragma mark - UIAccessibilityElement overrides | ||
|
|
||
| - (CGRect)accessibilityFrame { | ||
| return _semanticsObject.accessibilityFrame; | ||
| } | ||
|
|
||
| - (BOOL)isAccessibilityElement { | ||
| return NO; | ||
| } | ||
|
|
||
| - (id)accessibilityContainer { | ||
| return [_semanticsObject accessibilityContainer]; | ||
| } | ||
|
|
||
| - (BOOL)accessibilityScroll:(UIAccessibilityScrollDirection)direction { | ||
| return [_platformView accessibilityScroll:direction]; | ||
| - (NSArray*)accessibilityElements { | ||
| return @[ _platformView ]; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you can override the nativeAccessibility prop gettter to return the _platformView |
||
| } | ||
|
|
||
| @end | ||
|
|
@@ -882,12 +836,6 @@ - (nullable id)accessibilityElementAtIndex:(NSInteger)index { | |
|
|
||
| SemanticsObject* child = [_semanticsObject children][index - 1]; | ||
|
|
||
| // Swap the original `SemanticsObject` to a `PlatformViewSemanticsContainer` | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why was this pattern used in the first place? #8156
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't really remember a particular reason the old pattern was used. I don't think the new pattern was ever considered when I first implemented this. |
||
| if (child.node.IsPlatformViewNode()) { | ||
| child.platformViewSemanticsContainer.index = index; | ||
| return child.platformViewSemanticsContainer; | ||
| } | ||
|
|
||
| if ([child hasChildren]) | ||
| return [child accessibilityContainer]; | ||
| return child.nativeAccessibility; | ||
|
|
@@ -897,11 +845,6 @@ - (NSInteger)indexOfAccessibilityElement:(id)element { | |
| if (element == _semanticsObject) | ||
| return 0; | ||
|
|
||
| // FlutterPlatformViewSemanticsContainer is always the last element of its parent. | ||
| if ([element isKindOfClass:[FlutterPlatformViewSemanticsContainer class]]) { | ||
| return ((FlutterPlatformViewSemanticsContainer*)element).index; | ||
| } | ||
|
Comment on lines
-901
to
-903
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice, I found this pretty confusing when I was stepping through, part of the bug seemed to be that the index was set by one container, then accessed by another? |
||
|
|
||
| NSArray<SemanticsObject*>* children = [_semanticsObject children]; | ||
| for (size_t i = 0; i < [children count]; i++) { | ||
| SemanticsObject* child = children[i]; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should instead use
NS_UNAVAILABLEandNS_DESIGNATED_INITIALIZERfor this pattern.