聚焦非 UILabel titleView 时,VoiceOver 读取辅助功能标签两次 [英] VoiceOver reads accessibility label twice when focusing non-UILabel titleView

查看:37
本文介绍了聚焦非 UILabel titleView 时,VoiceOver 读取辅助功能标签两次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用 VoiceOver 时遇到了一个奇怪的问题.

I'm encountering a strange issue with VoiceOver.

目标:

  • 设置一个包含多个 UILabelUIStackView 作为我的 navigationItem.titleView.
  • 将堆栈视图标记为可访问性元素,并将其 accessibilityLabel 设置为适当的值.
  • 通过在 viewDidAppear(animated:) 中调用 UIAccessibility.post(notification: .screenChanged, argument: navigationItem.titleView) 将堆栈视图设置为初始 VoiceOver 焦点.
  • Set a UIStackView containing multiple UILabel's as my navigationItem.titleView.
  • Mark the stack view as an accessibility element and set its accessibilityLabel to an appropriate value.
  • Set the stack view as the initial VoiceOver focus by calling UIAccessibility.post(notification: .screenChanged, argument: navigationItem.titleView) inside viewDidAppear(animated:).

预期结果:

  • 当视图控制器出现时,焦点似乎在标题视图上,VoiceOver 会读取无障碍标签的内容一次.

实际结果:

  • VoiceOver 开始读取可访问性标签的内容,然后在中途(或有时在完成后)继续读取第二次.

如果我将 navigationItem.titleView 设置为 UILabel 的实例,则不会出现此问题.

This issue does not occur if I set navigationItem.titleView to an instance of UILabel.

有谁知道为什么会这样?这是 iOS 中的错误吗?

Does anyone know why this happens? Is it a bug in iOS?

我在这里建立了一个简单的项目来演示这个问题:https://github.com/rzulkoski/Focus-TitleView-Bug

I have set up a simple project demonstrating the issue here: https://github.com/rzulkoski/Focus-TitleView-Bug

推荐答案

第二次阅读标题的原因在于您的代码.

The reason why you have a second time reading of your title is in your code.

在您的 viewDidLoad 中,您设置了 VoiceOver 自动读出的堆栈视图可访问性标签,以通知用户更改.

In your viewDidLoad, you set the stackview accessibility label that VoiceOver automatically reads out to inform the user of the changing.

接下来,您通过 viewDidAppear 中的帖子通知此更改,VoiceOver 自然也会读出.

Next, you notify this changing with a post in your viewDidAppear that VoiceOver naturally reads out as well.

要防止这种行为,只需删除 setupNavigationItem 函数中的 stackView.accessibilityLabel = label.text 并将此代码段添加到您的私有惰性 var 标签 init 中:

To prevent from this behavior, just delete stackView.accessibilityLabel = label.text in your setupNavigationItem function and add this snippet in your private lazy var label init :

if (self.view.subviews.contains(stackView)) {
        stackView.accessibilityLabel = label.text
}

以这种方式更新 stackView.accessibilityLabel 不会触发 VoiceOver 通知用户并允许达到您的目的.

Updating the stackView.accessibilityLabel this way doesn't trigger VoiceOver to inform the user and allows to get your purpose.

但是,除非您重新排序呈现的元素.

However, I don't recommend to read out the title as the first element of a new page unless you reorder the presented elements.

VoiceOver 用户不会自然地猜到标题之前存在另一个元素:

VoiceOver users won't naturally guess that another element is present before the title :

  • They may not find a way to get back to the previous page.
  • They may be lost if they get the first element of the page with a 4 fingers simple-tap because they'll get the back button and not the title.

从技术上讲,您的问题已通过上面的一段代码解决,但从概念上讲,如果您仍想将标题作为第一个元素公开,我建议您对元素重新排序.

Technically, your problem is solved with the piece of code above but, conceptually, I suggest to reorder your elements if you still want to expose the title as the first element.

==========

编辑(解决方法)

关于技术问题,您在评论中说得对,由于 VoiceOver 读取标签,上述解决方案有效.

About the technical problem, you're right in your comment, this solution above works thanks to the label reading by VoiceOver.

我在您在初始帖子中提供的 git 分支中提交了一个解决方案.

I commited a solution in your git branch you gave in your initial post.

问题涉及 UIStackView,在这种情况下我无法解释,也无法按原样解决.

The problem deals with the UIStackView I cannot explain in this case and cannot solve neither as is.

为了达到您的目的,我为堆栈视图创建了一个 UIAccessibilityELement,它可以完美地访问和公开,无需重复阅读后通知.

To reach your purpose, I created a UIAccessibilityELement for the stackview that can be perfectly reached and exposed with no double reading with a postnotification.

我这样做是因为当标签在里面时我无法以编程方式获得 stackview 的新大小......也许创建一个 UIStackView 子类并进入它的 layoutSubviews 可能是诀窍?

I did that because I couldn't get programmatically the stackview new size when the labels are in... maybe creating a UIStackView subclass and get into its layoutSubviews could be the trick ?

这个解决方案应该作为一种解决方法,但我不知道 UIStackview 出现这种行为的原因.

This solution should work as a workaround but I don't know the reason why this behavior appears with a UIStackview.

==========

编辑(解决方案)

问题在于 navigationItemtitleView 的创建方式.实现目标的最佳方式是:

The problem is the way the titleView of the navigationItem is created. The best way to achieve your purpose is to :

  • 将 titleView 初始化为一个简单的 UIView,其框架与堆栈视图的框架相同.
  • 在指定其框架和可访问性属性后,将堆栈视图添加为子视图.
  • Initialize your titleView as a simple UIView whose frame is the same as the stackview's.
  • Add the stackview as a subview after having specified its frame and its accessibility properties.

在您的代码中按照以下步骤操作:

Follow the steps hereafter in your code :

  • 在 stackview 属性中添加 .header trait:

private lazy var stackView: UIStackView = {
    let stackView = UIStackView(frame: .zero)
    stackView.axis = .vertical
    stackView.alignment = .center
    stackView.distribution = .equalSpacing
    stackView.isAccessibilityElement = true
    stackView.accessibilityTraits = .header
    return stackView
}()

  • 更改switch...case..."代码部分中的 stackview case,如下所示:

  • Change the stackview case in your 'switch...case...' code section as below :

    case .stackView:
        label.text = "UIStackView"
        label.sizeToFit()
        stackView.addArrangedSubview(label)
    
        label2.text = subtitle
        label2.sizeToFit()
        stackView.addArrangedSubview(label2)
    
        stackView.frame.size.width = max(label.frame.width, label2.frame.width)
        stackView.frame.size.height = label.frame.height + label2.frame.height
    
        stackView.accessibilityLabel = label.text?.appending(", \(label2.text!)")
    
        navigationItem.titleView = UIView(frame: stackView.frame)
        navigationItem.titleView?.addSubview(stackView)
    }
    

  • 现在,postNotification 仅读取一次您的堆栈视图作为屏幕的第一个元素.

    Now, the postNotification reads out your stackview only once as the first element of your screen.

    这篇关于聚焦非 UILabel titleView 时,VoiceOver 读取辅助功能标签两次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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