使用UIAccessibilityPostNotification,画外音有很大的停顿

smm*_*zer 2 iphone accessibility ios voiceover

我正在为我的iPhone游戏添加辅助功能,并广泛使用UIAccessibilityPostNotification(UIAccessibilityAnnouncementNotification,@"string")来宣布游戏中发生的各种事情.它在99%的时间内运行良好,但我遇到了一个问题.

在所有情况下,配音通知都是从我添加到应用程序委托的单个方法执行的.

- (void)voiceoverAction:(NSString *)speakString delay:(NSTimeInterval) delay {
    if (![[[[UIDevice currentDevice] systemVersion] substringToIndex:1] isEqualToString:@"3"]) {
        if (UIAccessibilityIsVoiceOverRunning()) {
            UIAccessibilityPostNotification(UIAccessibilityAnnouncementNotification, speakString);
            if (delay > 0) {
                [NSThread sleepForTimeInterval:delay];
            }
        }
    }
}

延迟就在那里,所以在游戏中发生下一个事件之前就会发出通知.我找不到更好的方法来确保在一些动画或其他事件切断之前发出整个公告.

在每种情况下,只有一个在调用此方法时立即说出通知.在一种情况下,在说话之前有大约10秒的暂停.在这种情况下,即使我调试代码并设置断点并手动执行UIAccessibilityPostNotification行,该行也会执行,但没有任何反应.然后10秒钟后,iPhone没有在调试器中做任何事情,iPhone就开始说出公告了.

关于这一个公告的唯一特别之处在于它是从UIScrollView的touchesEnded:事件中调用的.其他公告是整个游戏循环的一部分,并非基于触摸事件.

知道什么可能导致画外音排队可访问性通知而不是立即说出来吗?

先谢谢,史蒂夫

Dav*_*ist 6

如果您只支持iOS 6和转发版,那么您可以使用UIAccessibilityAnnouncementDidFinishNotification以确保在继续之前完成通知.

你会像任何其他通知一样观察它

// Observe announcementDidFinish to know when an announcment finishes
// and if it succuded or not. 
[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(announcementFinished:)
                                             name:UIAccessibilityAnnouncementDidFinishNotification
                                           object:nil];
Run Code Online (Sandbox Code Playgroud)

您收到的通知附带公告文本以及是否已阅读所有文本或公告是否已中止.如果您有多个公告,那么您可以等待正确的公告.

// When an announcement finishes this will get called.
- (void)announcementFinished:(NSNotification *)notification {
    // Get the text and if it succeded (read the entire thing) or not
    NSString *announcment = notification.userInfo[UIAccessibilityAnnouncementKeyStringValue];
    BOOL wasSuccessful = [notification.userInfo[UIAccessibilityAnnouncementKeyWasSuccessful] boolValue];

    if (wasSuccessful) {
        // The entire announcement was read, you can continue.
    } else {
        // The announcement was aborted by something else being read ...
        // Decide what you want to do in this case. 
    } 
}
Run Code Online (Sandbox Code Playgroud)