UIAccessibilityLayoutChangedNotification和UIAccessibilityScreenChangedNotification之间的实际差异? [英] Actual difference between UIAccessibilityLayoutChangedNotification and UIAccessibilityScreenChangedNotification?

查看:392
本文介绍了UIAccessibilityLayoutChangedNotification和UIAccessibilityScreenChangedNotification之间的实际差异?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试确定在发布 UIAccessibilityLayoutChangedNotification UIAccessibilityScreenChangedNotification 时发生的具体情况。从我所看到的,我可以在任何地方互换使用它们,没有任何不同的事情发生。

I’m trying to ascertain what exactly happens differently when posting a UIAccessibilityLayoutChangedNotification, and a UIAccessibilityScreenChangedNotification. From what I can see, I can use them interchangeably everywhere and nothing different happens.

Apple文档只是说使用 LayoutChanged 当(例如)一个元素被隐藏或显示时,如果整个屏幕发生变化,使用 ScreenChanged ,但是我对他们做什么感兴趣提供这些信息,以及在使用其中一个时我应该看到的不同。

The Apple documentation simply says to use LayoutChanged when (for example) an element has been hidden or shown, and to use ScreenChanged if the entire screen changes, but I’m interested in what THEY do when I provide this information, and what I should see differently when using one or the other.

任何人都可以清楚地解释两者之间的实施差异吗?

Can anyone give a clear explanation of implementation differences between the two?

推荐答案

这两个通知用于视图上的动态内容,并将这些更改传达给屏幕阅读器用户的VoiceOver。这两个通知之间没有什么区别,除了它们的默认行为,以及ScreenChange通知的愚蠢的小boop beep。

These two notifications are for dynamic content on views, and communicating these changes to VoiceOver for screenreader users. There is little difference between these two notifications, except for their default behavior, and the silly little "boop beep" for ScreenChange notifications.

在两个实例中,参数

UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, arg);

表示要读出的字符串或屏幕元素,VoiceOver会将其焦点转移到。如果发生剧烈的背景变化,重点是将焦点发送到有意义的地方,或者宣布已经发生了这样的变化。从可访问性的角度来看,这两种方法都是可以接受的,尽管我更喜欢可能涉及最少量更改的方法。在简单的布局更改的情况下,几乎总是最好只宣布上下文更改,并将焦点保持在原来的位置。虽然有时会导致上下文更改的元素被隐藏,然后显然需要指示画外音来突出显示新内容,因为在这种情况下默认行为是未定义的,或者可能是确定性的,但是由一个完全不知道的框架决定关于你的应用程序!

Represents a string to be read out, or an on screen element, which VoiceOver will shift its focus to. In the event of dramatic context changes, it is important to send focus to a place that makes sense, or announce that such changes have taken place. Either approach is acceptable from an accessibility point of view, though I prefer approaches that involve the least amount of change possible. In the event of simple layout changes, it is almost always best just to announce the context change, and leave focus where it was. Though sometimes, the element that caused the context change is hidden, and then it is clearly necessary to direct voiceover to highlight new content, because the default behavior in this case is undefined, or perhaps deterministic, but determined by a framework that knows absolutely nothing about your app!

这两个事件之间的区别在于它们都完全相同,它们的默认行为。如果你给 UIAccessibilityLayoutChangedNotification 提供nil,就好像你什么也没做。如果为 UIAccessibilityScreenChangedNotification 提供nil参数,它将把焦点发送到视图层次结构中标记为accessibilityElement的第一个UIObject,一旦所有视图层次结构发生变化并且绘图完成。

The difference between the two events, given that they both do exactly the same thing, is in their default behavior. If you supply nil to the UIAccessibilityLayoutChangedNotification it is as if you have done nothing. If you supply a nil argument to the UIAccessibilityScreenChangedNotification it will send focus to the first UIObject in your view hierarchy that is marked as an accessibilityElement, once all view hierarchy changes and drawings are complete.

UIAccessibilityLayoutChangedNotification

UIAccessibilityLayoutChangedNotification 适用于动态表单。您希望让用户知道,根据他们在表单中做出的决定,可以使用新选项。例如,如果在表单中选择您是退伍军人,则可能会弹出表单的其他区域以提供更多输入,但这些区域可能已隐藏给其他不关心它们的用户。因此,您可以在用户交互后将焦点转移到这些元素:

A good use case example for UIAccessibilityLayoutChangedNotification is for dynamic forms. You want to let users know that, based on decisions they've made in the form, new options are available. For example, if in a form you select that you are a Veteran, additional areas of the form may pop up to provide more input, but these areas may have been hidden to other users who did not care about them. So you could shift focus to these elements after user interaction:

UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, firstNewFormElement);

这会将焦点转移到提供的元素,并宣布它的accessibilityLabel。

Which would shift focus to the provided element, and announce it's accessibilityLabel.

或者告诉他们新的表单元素在那里:

Or just tell them that the new form elements are there:

UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, @"Veterans form elements available");

哪会留下焦点,但VoiceOver会宣布退伍军人表格元素可用。

Which would leave focus where it is, but VoiceOver would announce "Veterans form elements available".

注意:我的iPad(8.1.2)上有这种特殊行为。

Note: This particular behavior is bugged on my iPad (8.1.2).

或者最后你可以这样做:

Or finally you could do this:

UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, nil);

哪个绝对没有:)。说真的,我甚至不认为a11y框架后端关心。这段特殊代码完全是浪费!

Which does absolutely nothing :). Seriously, I don't even think the a11y framework backend cares. This particular line of code is a complete waste!

UIAccessibilityScreenChangedNotification

一个好的 UIAccessibilityScreenChangedNotification 的用例示例是自定义选项卡式浏览情境。当整个屏幕(导航区域除外)发生变化时。你想让画外音知道基本上整个屏幕都改变了,但不是要聚焦第一个元素(你的第一个标签)而是要聚焦第一个内容元素。

A good use case example for the UIAccessibilityScreenChangedNotification is customized tabbed browsing situations. When the entire screen, with the exception of your navigation area, changes. You want to let voiceover know that essentially the entire screen changed, but NOT to focus the first element (your first tab) but to focus the first content element.

UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, firstNonGlobalNavElement);

哪个会播放boop beep声音,然后将焦点转移到全局导航栏下方。或者你可以这样做:

Which would play the "boop beep" sound and then shift focus to just beneath your global navigation bar. Or you could do this:

UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, @"You're on a new tab");

等待新标签加载,播放beep boop声音,宣布你在画外音中重新选择一个新标签,然后将焦点转移到屏幕上的第一个元素,然后宣布该元素的accessibilityLabel。 (PHEW!这很多!这对于屏幕阅读器用户来说是不和谐的。除非绝对必要,否则避免这种情况。)

Which would wait for the new tab to load, play the "beep boop" sound, announce "You're on a new tab" in voiceover, then shift focus to the first element on the screen, then announce the accessibilityLabel for that element. (PHEW! That's a lot! This is jarring for screen reader users. Avoid this scenario, unless absolutely necessary).

最后你当然可以这样做:

And finally you can of course do this:

UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, nil);    

相当于:

UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, firstA11yElement);

两者都会发出哔哔声声音,将VoiceOver焦点转移到第一个元素上屏幕,然后宣布它。

Both of which will play the "beep boop" sound, shift VoiceOver focus to the first element on the screen, and then announce it.

最后

在评论中有人提到缓存,我偶尔会在答案中评论A11y后端可能会或可能不会关心的事情。虽然有可能发生一些后端魔法,但我不相信这两种情况,后端都在乎。我说这是因为:

In a comment somebody mentioned caching, and I occasionally comment in my answer about things the A11y Backend may or may not care about. While it is certainly possible that there is some backend magic happening, I don't believe in either of these circumstances, the back end cares at all. The reason I say this is because:

如果你曾经使用过 UIAccessibilityContainer 协议,你可以看作查询您的容器视图。没有缓存。每当VoiceOver将焦点更改为容器中的新AccessibilityElement时,甚至 accessibilityElementCount 属性也会被ping。然后它会检查它所在的元素,请求下一个元素,等等。它的核心是处理动态情况。如果您在交互后将新元素插入容器中,它仍然会经历所有这些查询并且对它很好!此外,如果您覆盖UIAccessibility协议的属性,为了提供动态提示和标签,您还可以看到每次调用这些函数!因此,我认为A11y Framework后端从这些通知中收集了绝对零的信息。 VoiceOver需要完成其工作的唯一信息是它目前专注于Accessibility Element,并且这个元素是Accessibility Container。通知只是为了让您的应用对VoiceOver用户更有用。

If you've ever used the UIAccessibilityContainer protocol, you can watch as your container of views gets queried. There is no caching going on. Even the accessibilityElementCount property gets pinged each time VoiceOver changes focus to a new AccessibilityElement within your container. Then it goes through the process of checking which element it is on, asking for the next element, and so on. It is designed at its core to handle dynamic situations. If you were to insert a new element into your container after interaction, it would still go through all of these queries and be just fine about it! Furthermore, if you override the properties of the UIAccessibility protocol, in order to provide dynamic hints and labels, you can also see that these functions get called every time! As such, I believe that the A11y Framework backend gleans ABSOLUTELY ZERO information from these notifications. The only information VoiceOver needs to do its job is it's currently focused Accessibility Element, and this elements Accessibility Container. The notifications are simply there for you to make your app more usable for VoiceOver users.

想象一下,如果不是这种情况,Safari会发布这些通知多少次!! ! :)

Imagine if this weren't the case how many times Safari would post these notifications!!!! :)

这些特定的陈述只能由具有框架后端知识的人确认,他们使用代码,并且应该被视为猜想。情况可能是这是高度版本/实现依赖的。绝对愿意讨论这些问题!本文的其余部分非常具体。

These particular statements can only be confirmed by someone with backend knowledge of the framework, who works with the code, and should be viewed as conjecture. It could be the case that this is highly version/implementation dependent. Definitely open to discussion on these points! The rest of this post is pretty concrete.

供参考

最这是来自使用框架的经验,但如果你想进一步挖掘,这里有一个有用的参考。

Most of this comes from experience working with the frameworks, but here is a useful reference if you wish to dig further.

https://developer.apple.com/documentation/uikit/accessibility/uiaccessibility

https://developer.apple.com/documentation/uikit/uiaccessibilitylayoutchangednotification

https://developer.apple.com / documentation / uikit / uiaccessibilityscreenchangednotification

最后,我把一个愚蠢的小应用程序的开源仓库放在一起测试所有很棒。

And finally, an open source repo of the silly little app I put together to test all this stuff.

https:/ /github.com/chriscm2006/IOS-A11y-Api-Test

这篇关于UIAccessibilityLayoutChangedNotification和UIAccessibilityScreenChangedNotification之间的实际差异?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆