为什么UIAccessibilityNotification没有移动到正确的参数?

本教程将介绍为什么UIAccessibilityNotification没有移动到正确的参数?的处理方法,这篇教程是从别的地方看到的,然后加了一些国外程序员的疑问与解答,希望能对你有所帮助,好了,下面开始学习吧。

为什么UIAccessibilityNotification没有移动到正确的参数? 教程 第1张

问题描述

我在tableviewcell内部有一个UISwitch。该开关发出网络请求。UIActivityIndicator将替换开关,直到响应完成。
因此,UX流是这样的:

off --> loader --> on

轻触标签之前,辅助功能显示为:

label - value - hint
‘streaming - switch button off - double tap to toggle switch’

我的代码如下:

@IBAction func switchToggled(_ sender: Any) {
 toggle.isHidden = true
 activityIndicatorView.startAnimating()
 UIAccessibility.post(notification: .layoutChanged, argument: activityIndicatorView)

我还禁用了单元格本身的可访问性。

问题是辅助功能将如下所示:

$switchValue - activityIndicatorLabel-activityIndicatorValue - switchLabel switchValue
off - streaming - in progress - streaming - switch button on

我不确定为什么在我将切换的isHidden设置为true并发布辅助功能通知?‍♂️后,辅助功能仍然显示

我想从上面的☝️中省略,并将其读作如下:

$activityIndicatorLabel-activityIndicatorValue - switchLabel switchValue
streaming - in progress - streaming - switch button on

FWIW

UIAccessibility.post(notification: .screenChange, argument: activityIndicatorView)

获取所需的语音序列,但随后会产生新问题。也就是说,我听到"砰"的一声,这会让用户误以为他们在一个新的屏幕上。

奇怪的是,此通知移到了正确的项目,而另一个没有。我本以为这两个通知会创建相同的订单,但事实并非如此


编辑:

我已经调查过How to stop Text to Speech when Voiceover is speaking, or vice versa in Swift?

并且我正在观察UIAccessibilityElementFocusedNotification通知。我在userInfo中有三个项目。

▿ Optional<Dictionary<AnyHashable, Any>>
  ▿ some : 3 elements
 ▿ 0 : 2 elements
▿ key : AnyHashable("UIAccessibilityFocusedElementKey")
  - value : "UIAccessibilityFocusedElementKey"
- value : <UIActivityIndicatorView: 0x113b59350; frame = (794 20; 24 24); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x2811a91e0>>
 ▿ 1 : 2 elements
▿ key : AnyHashable("UIAccessibilityAssistiveTechnologyKey")
  - value : "UIAccessibilityAssistiveTechnologyKey"
- value : UIAccessibilityNotificationVoiceOverIdentifier
 ▿ 2 : 2 elements
▿ key : AnyHashable("UIAccessibilityUnfocusedElementKey")
  - value : "UIAccessibilityUnfocusedElementKey"
- value : <MyModule.MySwitch: 0x113b59540; baseClass = UISwitch; frame = (769 16.5; 51 31); hidden = YES; opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x2811a9120>>

有两件事我不知道怎么解决。

    这三件事来得不顺。这只是一个包含所有三个的通知。我想取消画外音,因为交换机没有对焦。我不想让人读到这一点。

    答案仍然没有解释怎么取消不需要的画外音。

推荐答案

不幸的是,Voice Over有很多缺陷(在它出现之初,它要好得多,但随着后来的iOS版本的变化,它变得更糟糕了)。强迫它改变行为是大量的"黑客行为",对于新的系统,它可能会再次以您不希望的方式运行。在说完之后,我将提出至少目前可以使用的解决方案。

首先,我必须指出暂停画外音不可能以编程方式实现,因为它会导致崩溃(check here)。因此

UIAccessibility.post(notification: .pauseAssistiveTechnology, argument: UIAccessibility.AssistiveTechnologyIdentifier.notificationVoiceOver)

无济于事。

使用UISwitch处理UITableViewCell的最佳方式是使用与Apple在iPhone设置中相同的方式(在整个单元上聚焦画外音)。因此您的开关不应该是辅助功能元素。

现在发现的最有趣的事情是-如果switch.isUserInteractionEnabled标志设置为true,则双击单元格将不会调用

tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath)

tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)

因此系统将以默认方式运行,并在滑块更改后直接读取新值。

但是,如果您要创建方法来设置新出列单元(在自定义单元类中),并在那里编写类似于

的内容

func setup() {
 slider.isUserInteractionEnabled = !UIAccessibility.isVoiceOverRunning //if VO is running you can't normally tap slider so it won't affect user experience
 NotificationCenter.default.removeObserver(self)
 NotificationCenter.default.addObserver(self, selector: #selector(setSwitchAccessibility), name: UIAccessibility.voiceOverStatusDidChangeNotification, object: nil)
}

@objc func setSwitchAccessibility() {
 slider.isUserInteractionEnabled = !UIAccessibility.isVoiceOverRunning //without VO user should be able to interact with switch directly or / and by selecting cell
}

然后您的表委托将被调用,允许执行一些自定义操作。必须观察画外音才能在关闭画外音时处理开关。

我理解的是通过"自定义"在will SelectRow中显示活动指示器,并通过

将焦点移动到那里

UIAccessibility.post(notification: .layoutChanged, argument: activityIndicatorView) 

并将辅助功能值设置为零(就在单元格上还原Voice Over Focus之前,再次将其设置为滑块辅助功能值)。

此外-从单元格中删除辅助功能值后,Voice Over将读取此单元格的辅助功能标签(如果存在)。在这种情况下,您需要临时覆盖此单元格的自定义属性(设置为nil)的默认accessibilityLabel,以便使用如下内容使其处于静默状态:

var labelToReturn: String? = ""

 override func accessibilityActivate() -> Bool {
  self.accessibilityValue = nil
  labelToReturn = nil
  return false
 }

 override var accessibilityLabel: String? {
  get {return labelToReturn == nil ? labelToReturn: super.accessibilityLabel}
  set {super.accessibilityLabel = newValue}
 }

请记住在从活动指示器中移除焦点之前将labelToReturn更改为其他内容。

好了关于为什么UIAccessibilityNotification没有移动到正确的参数?的教程就到这里就结束了,希望趣模板源码网找到的这篇技术文章能帮助到大家,更多技术教程可以在站内搜索。