我需要在执行某些操作时向我的应用程序的所有用户宣布一些文本。为此,我使用AVSpeechSynthesizer
。这很有效,除非您使用VoiceOver执行操作。由于VoiceOver向用户宣布了一些系统提供的信息,因此我的AVSpeechUtterance
同时播放,因此声音重叠。我如何排队讲话,以便在VoiceOver完成讲话之前不会播放?
答案 0 :(得分:3)
您可以通过观察VoiceOver活动来实现此目的。首先添加画外音通知观察员:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(voiceOverDidStop:) name:UIAccessibilityAnnouncementDidFinishNotification object:nil];
然后,在指定的方法中:
-(void)voiceOverDidStop:(NSNotification*)n {
NSString* msg;
NSNumber* finished;
msg = [[n userInfo] objectForKey:UIAccessibilityAnnouncementKeyStringValue];
finished = [[n userInfo] objectForKey:UIAccessibilityAnnouncementKeyWasSuccessful];
if(finished) {
// send the AVSpeechSynthsizer message
}
}
在处理你的应用程序之前,请记得删除观察!
您可以使用的另一种方法(如果适用)是编辑用户正在使用的对象的accessibilityLabel
和accessibilityHint
属性。将这些属性设置为@""
,以便VoiceOver知道对该对象没有任何说法。
希望这可以帮助你,即使我的答案来得太晚了: )
答案 1 :(得分:1)
检查VoiceOver是否正在投放,并使用您的消息发布UIAccessibilityAnnouncementNotification
,而不是使用AVSpeechSynthesizer
。
答案 2 :(得分:0)
我已经用 asyncAfter
完成了这个,代码是 SwiftUI,但我希望你能明白:
Button {
if !UIAccessibility.isVoiceOverRunning {
readOutLoud(translation)
}
} label: {
Image(systemName: "speaker.wave.3.fill")
}
.accessibilityElement()
.accessibilityLabel("Listen")
.accessibilityAction {
DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: {
readOutLoud(translation)
})
}
当按下按钮且 VoiceOver 未激活时,该按钮会读取文本。
当 VoiceOver 被激活时,文本将通过 accessibilityAction
以所需的延迟读取。