在VoiceOver停止说出文本后,使用AVSpeechSynthesizer宣布文本

时间:2015-03-28 00:05:17

标签: ios voiceover uiaccessibility avspeechsynthesizer

我需要在执行某些操作时向我的应用程序的所有用户宣布一些文本。为此,我使用AVSpeechSynthesizer。这很有效,除非您使用VoiceOver执行操作。由于VoiceOver向用户宣布了一些系统提供的信息,因此我的AVSpeechUtterance同时播放,因此声音重叠。我如何排队讲话,以便在VoiceOver完成讲话之前不会播放?

3 个答案:

答案 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
    }
}

在处理你的应用程序之前,请记得删除观察!

您可以使用的另一种方法(如果适用)是编辑用户正在使用的对象的accessibilityLabelaccessibilityHint属性。将这些属性设置为@"",以便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 以所需的延迟读取。