2

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

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

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

延迟是存在的,因此在游戏中的下一个事件发生之前会发出公告。我找不到更好的方法来确保在某些动画或其他事件中断之前说出整个公告。

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

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

知道什么可能导致画外音将可访问性通知排队并且不立即说出它吗?

在此先感谢,史蒂夫

4

3 回答 3

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];

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

// 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. 
    } 
}
于 2013-04-04T07:05:08.670 回答
2

无需传递延迟并进行睡眠,每当您调用此方法来说出您的公告时,您可以同时调度一个块以在延迟后执行dispatch_after以触发您的下一个事件。如果您愿意,也可以将块和延迟传递给此方法,然后在此方法中发送调度。

于 2012-09-27T16:17:14.540 回答
1

阅读我的评论。这是一个使用 NSThread sleepForTimeInterval 自己造成的问题。我已经多次阅读这是一种不好的形式,但我仍然没有看到更好的可访问性画外音公告的解决方案。我希望看到 Apple 为这个 UIAccessibilityPostNotification 调用创建一个块(因此也使用 Objective-C 方法),或者在画外音完成时创建一个回调。

于 2012-01-16T00:28:17.593 回答