您第二次阅读标题的原因在于您的代码。
在您的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 通知用户并允许达到您的目的。
但是,我不建议将标题作为新页面的第一个元素读出,除非您对呈现的元素重新排序。
VoiceOver 用户不会自然地猜测标题之前存在另一个元素:
- 他们可能找不到返回上一页的方法。
- 如果他们用4 根手指轻按来获得页面的第一个元素,他们可能会丢失,因为他们将获得后退按钮而不是标题。
从技术上讲,您的问题已通过上面的代码解决,但从概念上讲,如果您仍想将标题作为第一个元素公开,我建议重新排序您的元素。
==========
编辑(解决方法)
关于技术问题,您的评论是对的,上面的解决方案得益于 VoiceOver 的标签阅读。
我在您在初始帖子中提供的 git 分支中提交了一个解决方案。
问题涉及 UIStackView,在这种情况下我无法解释,也无法按原样解决。
为了达到您的目的,我UIAccessibilityELement
为 stackview 创建了一个可以完美地达到和公开的堆栈视图,无需通过 postnotification 进行重复阅读。
我这样做是因为当标签位于时我无法以编程方式获得stackview的新大小......也许创建一个 UIStackView 子类并进入它layoutSubviews
可能是诀窍?
该解决方案应该可以作为一种解决方法,但我不知道 UIStackview 出现此行为的原因。
==========
编辑(解决方案)
问题是创建的titleView
方式navigationItem
。实现目标的最佳方法是:
- 将您的 titleView 初始化为一个简单
UIView
的框架,其框架与 stackview 的相同。
- 在指定其框架及其可访问性属性后,将 stackview 添加为子视图。
请按照以下代码中的步骤操作:
.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 只会读出一次。