您第二次阅读标题的原因在于您的代码中。
In your viewDidLoad
,您可以设置 VoiceOver 自动读出的 stackview 辅助功能标签,以通知用户所做的更改。
接下来,您通过在您的帖子中通知此更改viewDidAppear
VoiceOver 也会自然地读出。
要防止这种行为,只需删除stackView.accessibilityLabel = label.text
在你的setupNavigationItem
函数并将此代码片段添加到您的私有惰性 var 标签 init 中:
if (self.view.subviews.contains(stackView)) {
stackView.accessibilityLabel = label.text
}
更新中stackView.accessibilityLabel
这种方式不会触发 VoiceOver 来通知用户并允许您了解您的目的。
但是,我不建议将标题读出为新页面的第一个元素,除非您reorder http://a11y-guidelines.orange.com/mobile_EN/dev-ios.html#reading-order所呈现的元素。
VoiceOver 用户自然不会猜测标题之前存在另一个元素:
- 他们可能找不到返回上一页的方法。
- 如果他们使用 a 获取页面的第一个元素,他们可能会丢失4个手指简单点击 http://a11y-guidelines.orange.com/mobile_EN/voiceover.html#PageFirstElement因为他们会得到后退按钮而不是标题。
从技术上来说,您的问题已通过上面的代码解决但是,从概念上讲,如果您仍然想将标题公开为第一个元素,我建议对元素重新排序。
=========
编辑(解决方法)
关于技术问题,您的评论是正确的,由于 VoiceOver 的标签读取,上述解决方案才有效。
我在你的第一篇文章中的 git 分支中提交了一个解决方案。
问题涉及 UIStackView 在这种情况下我无法解释,也无法按原样解决。
为了达到你的目的,我创建了一个UIAccessibilityELement
对于可以完美到达和暴露的堆栈视图,无需使用后通知进行双重读取。
我这样做是因为当标签位于...时我无法以编程方式获取 stackview 新大小...也许创建一个 UIStackView 子类并进入其layoutSubviews
可能是窍门?
该解决方案应该作为解决方法但我不知道为什么 UIStackview 会出现这种行为。
=========
编辑(解决方案)
问题是方法titleView
of the navigationItem
被建造。实现您的目的的最佳方法是:
- 将您的 titleView 初始化为一个简单的
UIView
其框架与 stackview 的框架相同。
- 指定其框架及其辅助功能后,将 stackview 添加为子视图。
请在您的代码中执行以下步骤:
-
Add the .header
stackview 属性中的特征:
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 .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
仅读出一次 stackview作为屏幕的第一个元素。