为什么未通过语音宣布UIAccessibility.post(通知:.announcement,参数:"arg")? [英] Why is UIAccessibility.post(notification: .announcement, argument: "arg") not announced in voice over?

查看:101
本文介绍了为什么未通过语音宣布UIAccessibility.post(通知:.announcement,参数:"arg")?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在iOS中使用Voice Over时,调用 UIAccessibility.post(notification:argument:)宣布字段错误实际上并没有宣布该错误.

When using Voice Over in iOS, calling UIAccessibility.post(notification:argument:) to announce a field error doesn't actually announce the error.

我有一个提交按钮,当聚焦按钮时,旁白会如您所愿地读取按钮标题.按下按钮时,旁白会再次读取标题.当按下提交"按钮时,我正在做一些验证;当出现字段错误时,我正在尝试通过调用以下内容来宣布它:

I have a submit button and, when focusing the button, voice over reads the button title as you would expect. When pressing the button, voice over reads the title again. When the submit button is pressed, I am doing some validation and, when there is a field error, I am trying to announce it by calling:

if UIAccessibility.isVoiceOverRunning {
    UIAccessibility.post(notification: .announcement, argument: "my field error")
}

足够有趣的是,如果我在调试器中的断点处停止,则会发生公告.当我不停在断点上时,通知就不会发生.

Interestingly enough, if I stop on a breakpoint in the debugger the announcement happens. When I don't stop on a breakpoint, the announcement doesn't happen.

该通知正在主线程上发布,并且,如果类似于 NotificationCenter.default ,我假定该通知是在其发布的同一线程上处理的.我已经尝试将调用分派到主队列,即使它已经在主线程上了,这似乎也不起作用.

The notification is posting on the main thread and, if is like NotificationCenter.default, I assume that it is handled on the same thread it was posted on. I have tried to dispatch the call to the main queue, even though it is already on the main thread, and that doesn't seem to work either.

我唯一能想到的是,在画外音完成阅读提交按钮标题之前,发布并观察了该通知,并且公告通知不会中断当前的画外音.

The only thing that I can think is that the notification is posted and observed before voice over is finished reading the submit button title and the announcement notification won't interrupt the current voice over.

在此方面,我将不胜感激.

I would really appreciate any help on this.

推荐答案

我能够使用重试机制使其工作,在该机制中,我注册为 UIAccessibility.announcementDidFinishNotification 的观察者,然后拉 userInfo 词典中的公告和成功状态.

I am able to get this to work using a retry mechanism where I register as an observer of the UIAccessibility.announcementDidFinishNotification and then pull the announcement and success status out of the userInfo dictionary.

如果成功状态为假,并且公告与我刚发送的公告相同,我将再次发布通知.重复此过程直到成功发布为止.

If the success status is false and the announcement is the same as the one I just sent, I post the notification again. This happens on repeat until the announcement was successful.

此方法显然存在多个问题,包括必须注销,如果另一个对象设法发布相同的公告会发生什么(这在实践中永远不会发生,但从理论上讲可能会发生),必须跟踪最近发送的公告,等等

There are obviously multiple problems with this approach including having to de-register, what happens if another object manages to post the same announcement (this shouldn't ever happen in practice but in theory it could), having to keep track of the last announcement sent, etc.

代码如下:

private var _errors: [String] = []
private var _lastAnnouncement: String = ""

init() {
    NotificationCenter.default.addObserver(
        self,
        selector: #selector(announcementFinished(_:)),
        name: UIAccessibility.announcementDidFinishNotification,
        object: nil
    )
}

func showErrors() {
    if !_errors.isEmpty {
        view.errorLabel.text = _errors.first!
        view.errorLabel.isHidden = false

        if UIAccessibility.isVoiceOverRunning {
            _lastAnnouncement = _errors.first!
            UIAccessibility.post(notification: .announcement, argument: _errors.first!)
        }
    } else {
        view.errorLabel.text = ""
        view.errorLabel.isHidden = true
    }
}

@objc func announcementFinished(_ sender: Notification) {
    guard let announcement = sender.userInfo![UIAccessibility.announcementStringValueUserInfoKey] as? String else { return }
    guard let success = sender.userInfo![UIAccessibility.announcementWasSuccessfulUserInfoKey] as? Bool else { return }

    if !success && announcement == _lastAnnouncement {
        _lastAnnouncement = _errors.first!
        UIAccessibility.post(notification: .announcement, argument: _errors.first!)
    }
}

问题在于将始终使用此重试机制,因为始终始终对 UIAccessibility.post(notification:.announcement,parameter:_errors.first!)进行首次调用(除非我在断点).我仍然不知道为什么第一篇文章总是失败.

The problem is that this retry mechanism will always be used because the first call to UIAccessibility.post(notification: .announcement, argument: _errors.first!) always (unless I am stopped on a breakpoint). I still don't know why the first post always fails.

这篇关于为什么未通过语音宣布UIAccessibility.post(通知:.announcement,参数:"arg")?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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