-
Notifications
You must be signed in to change notification settings - Fork 6k
Add a11y support for embedded iOS platform view #8156
Changes from 9 commits
3bcb1db
8fcf6b0
c036e80
05f77a3
b776a05
8ed39ee
a9a0c15
0e58ef8
4e670db
15c03ce
6fb37fe
3e57265
4a06b68
4ea581f
68251d8
c540565
4a29306
fb72727
5ff2ddc
fae2cc0
0d3bb16
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 |
|---|---|---|
|
|
@@ -113,7 +113,9 @@ class PlatformViewIOS; | |
|
|
||
| class AccessibilityBridge final { | ||
| public: | ||
| AccessibilityBridge(UIView* view, PlatformViewIOS* platform_view); | ||
| AccessibilityBridge(UIView* view, | ||
| PlatformViewIOS* platform_view, | ||
| FlutterPlatformViewsController* platform_views_controller); | ||
| ~AccessibilityBridge(); | ||
|
|
||
| void UpdateSemantics(blink::SemanticsNodeUpdates nodes, | ||
|
|
@@ -129,6 +131,10 @@ class AccessibilityBridge final { | |
|
|
||
| fml::WeakPtr<AccessibilityBridge> GetWeakPtr(); | ||
|
|
||
| FlutterPlatformViewsController* flutter_platform_views_controller() const { | ||
|
||
| return flutter_platform_views_controller_; | ||
| }; | ||
|
|
||
| void clearState(); | ||
|
|
||
| private: | ||
|
|
@@ -139,6 +145,7 @@ class AccessibilityBridge final { | |
|
|
||
| UIView* view_; | ||
| PlatformViewIOS* platform_view_; | ||
| FlutterPlatformViewsController* flutter_platform_views_controller_; | ||
|
||
| fml::scoped_nsobject<NSMutableDictionary<NSNumber*, SemanticsObject*>> objects_; | ||
| fml::scoped_nsprotocol<FlutterBasicMessageChannel*> accessibility_channel_; | ||
| fml::WeakPtrFactory<AccessibilityBridge> weak_factory_; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,6 +11,7 @@ | |
| #import <UIKit/UIKit.h> | ||
|
|
||
| #include "flutter/fml/logging.h" | ||
| #include "flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h" | ||
| #include "flutter/shell/platform/darwin/ios/platform_view_ios.h" | ||
|
|
||
| namespace { | ||
|
|
@@ -163,8 +164,9 @@ - (BOOL)isAccessibilityElement { | |
| // entire element tree looking for such a hit. | ||
|
|
||
| // We enforce in the framework that no other useful semantics are merged with these nodes. | ||
| if ([self node].HasFlag(blink::SemanticsFlags::kScopesRoute)) | ||
| if ([self node].HasFlag(blink::SemanticsFlags::kScopesRoute) || [self node].platformViewId > -1) | ||
|
||
| return false; | ||
|
|
||
| return ([self node].flags != 0 && | ||
| [self node].flags != static_cast<int32_t>(blink::SemanticsFlags::kIsHidden)) || | ||
| ![self node].label.empty() || ![self node].value.empty() || ![self node].hint.empty() || | ||
|
|
@@ -436,6 +438,20 @@ - (nullable id)accessibilityElementAtIndex:(NSInteger)index { | |
| return _semanticsObject; | ||
| } | ||
| SemanticsObject* child = [_semanticsObject children][index - 1]; | ||
|
|
||
| // This 'if' block handles adding accessibility support for the embedded platform view. | ||
| // We first check if the child is a semantic node for a platform view. | ||
| // If so, we add the platform view as accessibilityElements of the child. | ||
|
||
| shell::FlutterPlatformViewsController* flutterPlatformViewsController = | ||
| _bridge.get()->flutter_platform_views_controller(); | ||
|
||
| if (child.node.platformViewId > -1 && flutterPlatformViewsController) { | ||
goderbauer marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| NSObject<FlutterPlatformView>* platformViewProtocolObject = | ||
| flutterPlatformViewsController->GetPlatformViewByID(child.node.platformViewId); | ||
|
||
| UIView* platformView = [platformViewProtocolObject view]; | ||
|
||
| child.accessibilityElements = @[ platformView ]; | ||
| return child; | ||
| } | ||
|
|
||
| if ([child hasChildren]) | ||
| return [child accessibilityContainer]; | ||
| return child; | ||
|
|
@@ -485,9 +501,12 @@ - (BOOL)accessibilityScroll:(UIAccessibilityScrollDirection)direction { | |
|
|
||
| namespace shell { | ||
|
|
||
| AccessibilityBridge::AccessibilityBridge(UIView* view, PlatformViewIOS* platform_view) | ||
| AccessibilityBridge::AccessibilityBridge(UIView* view, | ||
| PlatformViewIOS* platform_view, | ||
| FlutterPlatformViewsController* platform_views_controller) | ||
| : view_(view), | ||
| platform_view_(platform_view), | ||
| flutter_platform_views_controller_(platform_views_controller), | ||
| objects_([[NSMutableDictionary alloc] init]), | ||
| weak_factory_(this), | ||
| previous_route_id_(0), | ||
|
|
@@ -660,6 +679,14 @@ - (BOOL)accessibilityScroll:(UIAccessibilityScrollDirection)direction { | |
| [object.parent.children replaceObjectAtIndex:positionInChildlist withObject:object]; | ||
| objects_.get()[@(node.id)] = object; | ||
| } | ||
|
|
||
| BOOL isPlatformViewNode = node.platformViewId > -1; | ||
| BOOL wasPlatformViewNode = object.node.platformViewId > -1; | ||
|
||
| if (wasPlatformViewNode && !isPlatformViewNode) { | ||
| // The node changed its type from platform view node to something else. In this | ||
| // case, we need to clean up the accessibility elements that we previously added. | ||
| object.accessibilityElements = nil; | ||
| } | ||
| } | ||
| } | ||
| return object; | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.