Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
sxychenjing
engine
提交
343af333
E
engine
项目概览
sxychenjing
/
engine
与 Fork 源项目一致
从无法访问的项目Fork
通知
3
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
E
engine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
343af333
编写于
6月 03, 2020
作者:
D
Dan Field
提交者:
GitHub
6月 03, 2020
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Live region announcements for iOS (#18798)
上级
a95882ba
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
86 addition
and
3 deletion
+86
-3
lib/ui/semantics.dart
lib/ui/semantics.dart
+6
-3
shell/platform/darwin/ios/framework/Source/SemanticsObject.h
shell/platform/darwin/ios/framework/Source/SemanticsObject.h
+1
-0
shell/platform/darwin/ios/framework/Source/SemanticsObject.mm
...l/platform/darwin/ios/framework/Source/SemanticsObject.mm
+19
-0
shell/platform/darwin/ios/framework/Source/SemanticsObjectTest.mm
...atform/darwin/ios/framework/Source/SemanticsObjectTest.mm
+38
-0
shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm
...tform/darwin/ios/framework/Source/accessibility_bridge.mm
+22
-0
未找到文件。
lib/ui/semantics.dart
浏览文件 @
343af333
...
...
@@ -483,9 +483,12 @@ class SemanticsFlag {
/// Platforms may use this information to make polite announcements to the
/// user to inform them of updates to this node.
///
/// An example of a live region is a [SnackBar] widget. On Android, A live
/// region causes a polite announcement to be generated automatically, even
/// if the user does not have focus of the widget.
/// An example of a live region is a [SnackBar] widget. On Android and iOS,
/// live region causes a polite announcement to be generated automatically,
/// even if the widget does not have accessibility focus. This announcement
/// may not be spoken if the OS accessibility services are already
/// announcing something else, such as reading the label of a focused
/// widget or providing a system announcement.
static
const
SemanticsFlag
isLiveRegion
=
SemanticsFlag
.
_
(
_kIsLiveRegionIndex
);
/// The semantics node has the quality of either being "on" or "off".
...
...
shell/platform/darwin/ios/framework/Source/SemanticsObject.h
浏览文件 @
343af333
...
...
@@ -91,6 +91,7 @@ constexpr int32_t kRootNodeId = 0;
uid
:(
int32_t
)
uid
NS_DESIGNATED_INITIALIZER
;
-
(
BOOL
)
nodeWillCauseScroll
:(
const
flutter
::
SemanticsNode
*
)
node
;
-
(
BOOL
)
nodeShouldTriggerAnnouncement
:(
const
flutter
::
SemanticsNode
*
)
node
;
-
(
void
)
collectRoutes
:(
NSMutableArray
<
SemanticsObject
*>*
)
edges
;
-
(
NSString
*
)
routeName
;
-
(
BOOL
)
onCustomAccessibilityAction
:(
FlutterCustomAccessibilityAction
*
)
action
;
...
...
shell/platform/darwin/ios/framework/Source/SemanticsObject.mm
浏览文件 @
343af333
...
...
@@ -180,6 +180,25 @@ flutter::SemanticsAction GetSemanticsActionForScrollDirection(
[
self
node
].
scrollPosition
!=
node
->
scrollPosition
;
}
/**
* Whether calling `setSemanticsNode:` with `node` should trigger an
* announcement.
*/
-
(
BOOL
)
nodeShouldTriggerAnnouncement
:(
const
flutter
::
SemanticsNode
*
)
node
{
// The node dropped the live region flag, if it ever had one.
if
(
!
node
||
!
node
->
HasFlag
(
flutter
::
SemanticsFlags
::
kIsLiveRegion
))
{
return
NO
;
}
// The node has gained a new live region flag, always announce.
if
(
!
[
self
node
].
HasFlag
(
flutter
::
SemanticsFlags
::
kIsLiveRegion
))
{
return
YES
;
}
// The label has updated, and the new node has a live region flag.
return
[
self
node
].
label
!=
node
->
label
;
}
-
(
BOOL
)
hasChildren
{
if
(
_node
.
IsPlatformViewNode
())
{
return
YES
;
...
...
shell/platform/darwin/ios/framework/Source/SemanticsObjectTest.mm
浏览文件 @
343af333
...
...
@@ -64,4 +64,42 @@ class MockAccessibilityBridge : public AccessibilityBridgeIos {
XCTAssertEqualObjects
(
parent
.
children
,
@[
child2
]);
}
-
(
void
)
testShouldTriggerAnnouncement
{
fml
::
WeakPtrFactory
<
flutter
::
AccessibilityBridgeIos
>
factory
(
new
flutter
::
MockAccessibilityBridge
());
fml
::
WeakPtr
<
flutter
::
AccessibilityBridgeIos
>
bridge
=
factory
.
GetWeakPtr
();
SemanticsObject
*
object
=
[[
SemanticsObject
alloc
]
initWithBridge
:
bridge
uid
:
0
];
// Handle nil with no node set.
XCTAssertFalse
([
object
nodeShouldTriggerAnnouncement
:
nil
]);
// Handle initial setting of node with liveRegion
flutter
::
SemanticsNode
node
;
node
.
flags
=
static_cast
<
int32_t
>
(
flutter
::
SemanticsFlags
::
kIsLiveRegion
);
node
.
label
=
"foo"
;
XCTAssertTrue
([
object
nodeShouldTriggerAnnouncement
:
&
node
]);
// Handle nil with node set.
[
object
setSemanticsNode
:
&
node
];
XCTAssertFalse
([
object
nodeShouldTriggerAnnouncement
:
nil
]);
// Handle new node, still has live region, same label.
XCTAssertFalse
([
object
nodeShouldTriggerAnnouncement
:
&
node
]);
// Handle update node with new label, still has live region.
flutter
::
SemanticsNode
updatedNode
;
updatedNode
.
flags
=
static_cast
<
int32_t
>
(
flutter
::
SemanticsFlags
::
kIsLiveRegion
);
updatedNode
.
label
=
"bar"
;
XCTAssertTrue
([
object
nodeShouldTriggerAnnouncement
:
&
updatedNode
]);
// Handle dropping the live region flag.
updatedNode
.
flags
=
0
;
XCTAssertFalse
([
object
nodeShouldTriggerAnnouncement
:
&
updatedNode
]);
// Handle adding the flag when the label has not changed.
updatedNode
.
label
=
"foo"
;
[
object
setSemanticsNode
:
&
updatedNode
];
XCTAssertTrue
([
object
nodeShouldTriggerAnnouncement
:
&
node
]);
}
@end
shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm
浏览文件 @
343af333
...
...
@@ -84,6 +84,7 @@ void AccessibilityBridge::UpdateSemantics(flutter::SemanticsNodeUpdates nodes,
flutter
::
CustomAccessibilityActionUpdates
actions
)
{
BOOL
layoutChanged
=
NO
;
BOOL
scrollOccured
=
NO
;
BOOL
needsAnnouncement
=
NO
;
for
(
const
auto
&
entry
:
actions
)
{
const
flutter
::
CustomAccessibilityAction
&
action
=
entry
.
second
;
actions_
[
action
.
id
]
=
action
;
...
...
@@ -93,6 +94,7 @@ void AccessibilityBridge::UpdateSemantics(flutter::SemanticsNodeUpdates nodes,
SemanticsObject
*
object
=
GetOrCreateObject
(
node
.
id
,
nodes
);
layoutChanged
=
layoutChanged
||
[
object
nodeWillCauseLayoutChange
:
&
node
];
scrollOccured
=
scrollOccured
||
[
object
nodeWillCauseScroll
:
&
node
];
needsAnnouncement
=
[
object
nodeShouldTriggerAnnouncement
:
&
node
];
[
object
setSemanticsNode
:
&
node
];
NSUInteger
newChildCount
=
node
.
childrenInTraversalOrder
.
size
();
NSMutableArray
*
newChildren
=
...
...
@@ -133,6 +135,26 @@ void AccessibilityBridge::UpdateSemantics(flutter::SemanticsNodeUpdates nodes,
}
else
if
(
object
.
platformViewSemanticsContainer
)
{
object
.
platformViewSemanticsContainer
=
nil
;
}
if
(
needsAnnouncement
)
{
// Try to be more polite - iOS 11+ supports
// UIAccessibilitySpeechAttributeQueueAnnouncement which should avoid
// interrupting system notifications or other elements.
// Expectation: roughly match the behavior of polite announcements on
// Android.
NSString
*
announcement
=
[[[
NSString
alloc
]
initWithUTF8String
:
object
.
node
.
label
.
c_str
()]
autorelease
];
if
(
@available
(
iOS
11.0
,
*
))
{
UIAccessibilityPostNotification
(
UIAccessibilityAnnouncementNotification
,
[[[
NSAttributedString
alloc
]
initWithString:
announcement
attributes:
@{
UIAccessibilitySpeechAttributeQueueAnnouncement
:
@YES
}]
autorelease
]);
}
else
{
UIAccessibilityPostNotification
(
UIAccessibilityAnnouncementNotification
,
announcement
);
}
}
}
SemanticsObject
*
root
=
objects_
.
get
()[
@
(
kRootNodeId
)];
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录