使用 VoiceOver 将 UITextField 读取为数字

Make UITextField with VoiceOver read numbers as digits

我们的应用程序有几个 UITextField 用户可以在其中输入字母数字输入代码,例如 "AA149873A"。

我们希望语音将这些读为 "A A 1 4 9 8 7 2 A",但它却将数字读为数字:"One hundred and forty nine thousand, eight hundred and seventy three"。

是否有某种方法可以配置 UITextField 使其知道其内容不应该被视为数字,而是单个数字?

谢谢。

从 iOS13 开始,可以添加字符串属性来直接画外音发声,将字符串拼写为单独的字母和数字。

我还没有找到一种方法来指示 UITextField 将此属性添加到其内容中。但是,UITextField 子类可以覆盖它的 accessibilityValue 来实现这一点。

此处给出的子类添加了一个属性来启用或禁用此行为。

final class AccessibilityTextField: UITextField {

    var isAlphanumeric: Bool = false

    override public var accessibilityAttributedValue: NSAttributedString? {
        get {
            guard let text = text, !text.isEmpty else {
                return nil
            }

            return NSAttributedString(string: text, attributes: valueAttributes)
        }

        set {
            // Ignore these values.
            _ = newValue
        }
    }

    private var valueAttributes: [NSAttributedString.Key: Any] {
        guard #available(iOS 13.0, *), isAlphanumeric else {
            return [:]
        }

        return [.accessibilitySpeechSpellOut: true]
    }
}

here that doesn't use the iOS 13 feature . accessibilitySpeechSpellOut. However, I've seen it suggested that this is not ideal for brail output systems 中给出了另一种方法,因为他们也使用 accessibilityLabel。也许这是 iOS 13 系统之前的一个很好的回退。

We'd like voice over to read these as "A A 1 4 9 8 7 2 A", but it instead reads the digits as a number: "One hundred and forty nine thousand, eight hundred and seventy three".

达到目标最快的方法是UITextFieldaccessibilityValue中的每个字符之间添加空格,如下所示:

class AccessibilityTextField: UITextField {

    var _str: String?
    override var text: String? {
        get { return _str}
        set {
            _str = newValue!
            accessibilityValue = _str!.map{String([=10=])}.joined(separator: " ")
        }
    }

    convenience init() { self.init() }

    required init?(coder: NSCoder) { super.init(coder: coder) }
}

我没有实现所有文本字段委托的东西来测试它⟹我只创建了一个空白项目 UITextField 添加了 "BB0024FG"纯文本并更改了我的视图控制器 viewDidAppear 中的文本:

myTextField.text = "AA14987A"

最后,VoiceOver 一个接一个地拼写出每个字符,而没有读出最初的纯文本。

根据这个原理,您可以通过一种方式让 VoiceOver 知道 UITextField 内容必须被视为单独的数字