为什么UIAccessibilityNotification没有移动到正确的参数? [英] Why isn't UIAccessibilityNotification not moving to correct argument?

查看:88
本文介绍了为什么UIAccessibilityNotification没有移动到正确的参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在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并发布辅助功能通知🤷‍♂️后,辅助功能仍然显示

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

$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>>

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

  1. 这三件事来得不顺。这只是一个包含所有三个的通知。我想取消画外音,因为交换机没有对焦。我不想让人读到这一点。
  2. 答案仍然没有解释如何取消不需要的画外音。

推荐答案

不幸的是,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没有移动到正确的参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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