以下の形式の電話番号があります
1-1xx-2xx-9565
現在、VO では「One (ポーズ) One xx (ポーズ) two xx (ポーズ) - 9,565 」と読みます。
VO は、「One (一時停止) One xx (一時停止) two xx (一時停止) 9 5 6 5」と読みます。
何が問題なのですか?これは間違った電話形式ですか?
以下の形式の電話番号があります
1-1xx-2xx-9565
現在、VO では「One (ポーズ) One xx (ポーズ) two xx (ポーズ) - 9,565 」と読みます。
VO は、「One (一時停止) One xx (一時停止) two xx (一時停止) 9 5 6 5」と読みます。
何が問題なのですか?これは間違った電話形式ですか?
何が起こっているのかを分析しましょう。VoiceOver は、提示しているテキストが電話番号であることを認識せず、テキストの文のように扱います。そのテキストでは、明確なコンポーネントを見つけて適切に読み取ろうとします。たとえば、「マスクメロンを 60 個購入」というテキストには、「購入」、「60」、「マスクメロン」の 3 つのコンポーネントがあります。1 つ目はテキストであり、テキストとして読み取られます。2 つ目は純粋に数値であり、「sixty」と読むのが最適です。3 つ目はテキストとして読み取られます。
(私は実際の実装について話しているのではなく、単に推論しています。)
1-1xx-2xx-9565を左から右に読むと、最初の別個のコンポーネントは「1」であり、それ自体が数値であり、「1」として読み取られます。電話番号が「12-1xx」で始まる場合、最初のコンポーネントは純粋に数字であるため、「12」と読み取られます。
次のコンポーネントは、見方によって「1xx」または「-1xx」です。どちらの場合も、数字と文字の組み合わせです。たとえば、純粋な数値ではなく、テキストとして読み上げられます。そのコンポーネントに「-」を含めると、読み上げられないハイフンとして解釈されます。そのため、そのコンポーネントの「-」は読み上げられません。次のコンポーネント ("-2xx") も同様に処理されます。
最後のコンポーネントは「-9565」で、有効な数値であることがわかります。マスクメロンの文に見られるように、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 7UIAccessibilitySpeechAttributePunctuation
では、属性文字列の属性を使用して発音方法を変更することもできます。
属性付き文字列の音声属性
属性付き文字列内のテキストに適用して、そのテキストの発音方法を変更できる属性。
UIAccessibilitySpeechAttributePunctuation
このキーの値は
NSNumber
、ブール値として解釈する必要があるオブジェクトです。値が の場合YES
、テキスト内のすべての句読点が読み上げられます。これは、句読点が関連するコードまたはその他のテキストに使用できます。iOS 7.0 以降で利用できます。
で宣言されてい
UIAccessibilityConstants.h
ます。
iOS 13 以降では、 -NSAttributedString.Key.accessibilitySpeechSpellOut
を使用して、指定された文字列 (または文字列の範囲) の各文字を読み取るaccessibilityAttributedLabel
ことができます。VoiceOver
たとえば、次のようになります。
yourView.accessibilityAttributedLabel = NSAttributedString(string: yourText, attributes: [.accessibilitySpeechSpellOut: true])
最後の数字の各桁と最後の数字の後にカンマを追加するだけです。これにより、ボイスオーバーが前の数字と同じように最後の数字を読み上げます。
あなたの番号の例:- 1-1xx-2xx-9565 アクセシビリティラベル:- 1-1xx-2xx-9,5,6,5,
すべての文字を個別に綴りたい場合、簡単な解決策は文字をコンマ「,」で区切ることです。
文字列拡張を使用して文字列を変換できます。
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()