MPMediaPickerController 无法使用 VoiceOver 宣布控件
MPMediaPickerController fails to announce controls with VoiceOver
我正在调试一个需要使用 VoiceOver 的完全辅助功能的应用程序,其中一项功能要求用户播放 select 首歌曲。该应用程序使用 MPMediaPicker。问题是 MPMediaPicker 并没有真正满足 VoiceOver 的可访问性要求,例如它没有宣布列表中的元素是否 selected 或没有,当用户 select 一个元素时它没有明确宣布,当搜索时它不会宣布列表中 selected 元素的数量,因为列表会被修剪,更糟糕的是,当按钮添加所有歌曲时它根本不会宣布任何内容 selected(它只是保持沉默)。
在我看来,对于一个如此广泛使用的标准组件来说,这些都是相当大的疏忽,我想知道我能做些什么来为我的客户修复这些问题,因为它在 Apple 文档中明确表示我不能子类 MPMediaPickerController 也不操纵其私有视图层次结构。
令人担忧的是,我的应用程序也使用标准组件来 select 联系人,这似乎也有类似的问题。
谢谢。
编辑:
该应用程序使用此代码显示 MPMediaPickerViewController,我认为它是相当标准的(可能有点过时,因为它仍然使用 retain/releases)
MPMediaPickerController *picker = [[MPMediaPickerController alloc] initWithMediaTypes: MPMediaTypeAnyAudio];
[picker setDelegate: self];
[picker setAllowsPickingMultipleItems: YES];
picker.prompt = NSLocalizedString (@"...", "...");
[[myAppDelegate instance] presentModalViewController: picker animated: YES];
[picker release];
presentModalViewController 是这样的:
- (void)presentModalViewController:(UIViewController *)modalViewController animated:(BOOL)animated {
UIViewController *c = self.window.rootViewController;
while ([c presentedViewController]) {
c = [c presentedViewController];
}
[c presentModalViewController:modalViewController animated:animated];
}
画外音中缺少的通知属于显示为 selection 进程的一部分以及 MPMediaPickerController 层次结构中的组件,因此我不知道如何访问它们。
上面的代码在属于 NavigationController 的 ViewController 的简单 (+) 右栏按钮的 IBAction 中调用。
进一步说明:
最小概念验证:在 Xcode 中创建一个默认的单页 iOS 应用程序。添加@import MediaPlayer;然后将此代码添加到 ViewController。
- (void)viewDidAppear:(BOOL)animated {
MPMediaPickerController *picker = [[MPMediaPickerController alloc] initWithMediaTypes: MPMediaTypeAnyAudio];
[picker setDelegate: self];
[picker setAllowsPickingMultipleItems: YES];
picker.prompt = NSLocalizedString (@"...", "...");
[self presentViewController:picker animated:true completion:^{
}];
}
在激活 VoiceOver 的情况下启动应用程序,然后 select 或导航到单元格 "Add All Song":VoiceOver 不会以任何方式宣布该项目。
我认为这总结得很好。从 Apple 文档中参考 MPMediaPickerController
:
This is a preliminary document for an API or technology in development. Apple is supplying this information to help you plan for the adoption of the technologies and programming interfaces described herein for use on Apple-branded products. This information is subject to change, and software implemented according to this document should be tested with final operating system software and final documentation. Newer versions of this document may be provided with future betas of the API or technology.
此控件不完整,而且可能永远不会完整,因为自 iOS 3.0 以来,它已被视为 "beta" API。
此外,总结一下我的发现,无法使此控件可访问。我可以尝试一下它的视图,每次我能够添加额外的标签时,它很快就会被覆盖和重置。每次标签被控件默认行为覆盖时,找到正确的回调来重置标签将很困难(不可能),显然我们不能覆盖单个元素的 UIAccessibilityProtocol
方法,因为它们不是我们实例化的控件。我们已经实例化了全局控件,它正在为我们绘制一切。最后,审阅者会认为这是访问私人 APIs,因此无论如何都不允许在 App Store 上使用。
结论:为了提供您希望的辅助功能支持,您将不得不手动实现类似的控件。
我正在调试一个需要使用 VoiceOver 的完全辅助功能的应用程序,其中一项功能要求用户播放 select 首歌曲。该应用程序使用 MPMediaPicker。问题是 MPMediaPicker 并没有真正满足 VoiceOver 的可访问性要求,例如它没有宣布列表中的元素是否 selected 或没有,当用户 select 一个元素时它没有明确宣布,当搜索时它不会宣布列表中 selected 元素的数量,因为列表会被修剪,更糟糕的是,当按钮添加所有歌曲时它根本不会宣布任何内容 selected(它只是保持沉默)。
在我看来,对于一个如此广泛使用的标准组件来说,这些都是相当大的疏忽,我想知道我能做些什么来为我的客户修复这些问题,因为它在 Apple 文档中明确表示我不能子类 MPMediaPickerController 也不操纵其私有视图层次结构。 令人担忧的是,我的应用程序也使用标准组件来 select 联系人,这似乎也有类似的问题。
谢谢。
编辑: 该应用程序使用此代码显示 MPMediaPickerViewController,我认为它是相当标准的(可能有点过时,因为它仍然使用 retain/releases)
MPMediaPickerController *picker = [[MPMediaPickerController alloc] initWithMediaTypes: MPMediaTypeAnyAudio];
[picker setDelegate: self];
[picker setAllowsPickingMultipleItems: YES];
picker.prompt = NSLocalizedString (@"...", "...");
[[myAppDelegate instance] presentModalViewController: picker animated: YES];
[picker release];
presentModalViewController 是这样的:
- (void)presentModalViewController:(UIViewController *)modalViewController animated:(BOOL)animated {
UIViewController *c = self.window.rootViewController;
while ([c presentedViewController]) {
c = [c presentedViewController];
}
[c presentModalViewController:modalViewController animated:animated];
}
画外音中缺少的通知属于显示为 selection 进程的一部分以及 MPMediaPickerController 层次结构中的组件,因此我不知道如何访问它们。 上面的代码在属于 NavigationController 的 ViewController 的简单 (+) 右栏按钮的 IBAction 中调用。
进一步说明: 最小概念验证:在 Xcode 中创建一个默认的单页 iOS 应用程序。添加@import MediaPlayer;然后将此代码添加到 ViewController。
- (void)viewDidAppear:(BOOL)animated {
MPMediaPickerController *picker = [[MPMediaPickerController alloc] initWithMediaTypes: MPMediaTypeAnyAudio];
[picker setDelegate: self];
[picker setAllowsPickingMultipleItems: YES];
picker.prompt = NSLocalizedString (@"...", "...");
[self presentViewController:picker animated:true completion:^{
}];
}
在激活 VoiceOver 的情况下启动应用程序,然后 select 或导航到单元格 "Add All Song":VoiceOver 不会以任何方式宣布该项目。
我认为这总结得很好。从 Apple 文档中参考 MPMediaPickerController
:
This is a preliminary document for an API or technology in development. Apple is supplying this information to help you plan for the adoption of the technologies and programming interfaces described herein for use on Apple-branded products. This information is subject to change, and software implemented according to this document should be tested with final operating system software and final documentation. Newer versions of this document may be provided with future betas of the API or technology.
此控件不完整,而且可能永远不会完整,因为自 iOS 3.0 以来,它已被视为 "beta" API。
此外,总结一下我的发现,无法使此控件可访问。我可以尝试一下它的视图,每次我能够添加额外的标签时,它很快就会被覆盖和重置。每次标签被控件默认行为覆盖时,找到正确的回调来重置标签将很困难(不可能),显然我们不能覆盖单个元素的 UIAccessibilityProtocol
方法,因为它们不是我们实例化的控件。我们已经实例化了全局控件,它正在为我们绘制一切。最后,审阅者会认为这是访问私人 APIs,因此无论如何都不允许在 App Store 上使用。
结论:为了提供您希望的辅助功能支持,您将不得不手动实现类似的控件。