我有以下格式的电话号码
1-1xx-2xx-9565
目前VO读作“一(停顿)一xx(停顿)二xx(停顿)减九千五百六十五”。
VO应该读作“一(停顿)一xx(停顿)二xx(停顿)九五六五”。
可能是什么问题呢?这是错误的电话格式吗?
我有以下格式的电话号码
1-1xx-2xx-9565
目前VO读作“一(停顿)一xx(停顿)二xx(停顿)减九千五百六十五”。
VO应该读作“一(停顿)一xx(停顿)二xx(停顿)九五六五”。
可能是什么问题呢?这是错误的电话格式吗?
让我们分解正在发生的事情。VoiceOver 不知道您正在呈现的文本是一个电话号码,并将其视为一个文本句子。在该文本中,它试图找到不同的组件并适当地阅读它们。例如,文本“buy 60 cantaloupes”有 3 个组件,“buy”、“60”和“cantaloupes”。第一个是文本,读成文本,第二个是纯数字,最好读成“六十”,第三个读成文本。
(我不是在谈论实际的实现,只是在推理。)
如果您从左到右读取1-1xx-2xx-9565,则第一个不同的组件是“1”,它本身是数字并被读取为“1”。如果电话号码以“12-1xx”开头,那么第一个组件将被读作“十二”,因为它纯粹是数字。
下一个组件是“1xx”或“-1xx”,具体取决于您如何看待它。在任何一种情况下,它都是数字和字母的组合,例如,它不是纯粹的数字,因此被读出为文本。如果您在该组件中包含“-”,则会将其解释为不读出的连字符。这就是为什么永远不会为该组件读出“-”的原因。下一个组件(“-2xx”)以相同的方式处理。
最后一个组件是“-9565”,它是一个有效数字。如 cantaloupe 句子中所示,VoiceOver 将其读取为数字,在这种情况下,“-”不再被解释为连字符而是“减号”。
在您的应用程序中与 Voice Over 一起使用的任何标签、视图或其他元素上,当您更了解您希望如何阅读文本时,您可以提供自己的“可访问性标签”。这是通过简单地将您自己的字符串分配给accessibilityLabel
属性来完成的。
现在,您可以通过许多不同的方式创建一个合适的字符串,在您的情况下一个非常简单的方法是在任何地方添加空格,以便单独读取每个数字。但是,它对我来说似乎有点脆弱,所以我继续使用数字格式化程序将各个数字转换为它们的文本表示形式。
NSString *phoneNumber = @"1-1xx-2xx-9565";
// we want to know if a character is a number or not
NSCharacterSet *numberCharacters = [NSCharacterSet characterSetWithCharactersInString:@"0123456789"];
// we use this formatter to spell out individual numbers
NSNumberFormatter *spellOutSingleNumber = [NSNumberFormatter new];
spellOutSingleNumber.numberStyle = NSNumberFormatterSpellOutStyle;
NSMutableArray *spelledOutComonents = [NSMutableArray array];
// loop over the phone number add add the accessible variants to the array
[phoneNumber enumerateSubstringsInRange:NSMakeRange(0, phoneNumber.length)
options:NSStringEnumerationByComposedCharacterSequences
usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
// check if it's a number
if ([substring rangeOfCharacterFromSet:numberCharacters].location != NSNotFound) {
// is a number
NSNumber *number = @([substring integerValue]);
[spelledOutComonents addObject:[spellOutSingleNumber stringFromNumber:number]];
} else {
// is not a number
[spelledOutComonents addObject:substring];
}
}];
// finally separate the components with spaces (so that the string doesn't become "ninefivesixfive".
NSString *yourAccessiblePhoneNumber = [spelledOutComonents componentsJoinedByString:@" "];
当我运行它时的结果是
one - one x x - two x x - nine five six five
如果您需要对您的电话号码进行其他修改以使其正确读取,那么您可以这样做。我怀疑你会在你的应用中使用不止一个地方,所以创建一个自定义的 NSFormatter 可能是一个好主意。
在 iOS 7 上,您还可以使用UIAccessibilitySpeechAttributePunctuation
属性字符串上的属性来更改其发音方式。
属性字符串的语音属性
您可以应用于属性字符串中的文本以修改该文本的发音方式的属性。
UIAccessibilitySpeechAttributePunctuation
这个键的值是一个
NSNumber
你应该解释为布尔值的对象。当值为 时YES
,将读出文本中的所有标点符号。您可以将其用于标点符号相关的代码或其他文本。在 iOS 7.0 及更高版本中可用。
中宣布
UIAccessibilityConstants.h
。
从 iOS 13 开始,您可以使用 -NSAttributedString.Key.accessibilitySpeechSpellOut
作为 aaccessibilityAttributedLabel
来VoiceOver
读取提供的字符串(或字符串范围)的每个字母。
例如:
yourView.accessibilityAttributedLabel = NSAttributedString(string: yourText, attributes: [.accessibilitySpeechSpellOut: true])
如果要单独拼写所有字符,一个简单的解决方案是用逗号“,”分隔字符。
您可以使用字符串扩展来转换字符串:
extension String
{
/// Returns string suitable for accessibility (voice over). All characters will be spelled individually.
func stringForSpelling() -> String
{
return stringBySeparatingCharactersWithString(",")
}
/// Inserts a separator between all characters
func stringBySeparatingCharactersWithString(separator: String) -> String
{
var s = ""
// Separate all characters
let chars = self.characters.map({ String($0) })
// Append all characters one by one
for char in chars {
// If there is already a character, append separator before appending next character
if s.characters.count > 0 {
s += separator
}
// Append next character
s += char
}
return s
}
}
然后在这样的代码中使用它:
myLabel.accessibilityLabel = myString.stringForSpelling()
只需在最后一个数字的每个数字以及最后一个数字之后添加一个逗号。这将确保旁白读取最后一个数字与之前的数字相同。
例如您的号码:- 1-1xx-2xx-9565 无障碍标签:- 1-1xx-2xx-9,5,6,5,
这是Swift中的代码
public func retrieveAccessiblePhoneNumber(phoneNumber: String) -> String {
// We want to know if a character is a number or not
let characterSet = NSCharacterSet(charactersInString: "0123456789")
// We use this formatter to spell out individual numbers
let numberFormatter = NSNumberFormatter()
numberFormatter.numberStyle = .SpellOutStyle
var spelledOutComponents = [String]()
let range = Range<String.Index>(start: phoneNumber.startIndex, end: phoneNumber.endIndex)
// Loop over the phone number add add the accessible variants to the array
phoneNumber.enumerateSubstringsInRange(range,
options: NSStringEnumerationOptions.ByComposedCharacterSequences) { (substring, substringRange, enclosingRange, stop) -> () in
// Check if it's a number
if let substr = substring where substr.rangeOfCharacterFromSet(characterSet) != nil {
if let number = Int(substr) {
// Is a number
let nsNumber = NSNumber(integer: number)
spelledOutComponents.append(numberFormatter.stringFromNumber(nsNumber)!)
}
} else {
// Is not a number
spelledOutComponents.append(substring!)
}
}
// Finally separate the components with spaces (so that the string doesn't become "ninefivesixfive".
return spelledOutComponents.joinWithSeparator(" ")
}