我有一个 UITableViewCell,其中每行都包含一个 UICollectionViewCell。此集合视图具有显示在单元格顶部的补充视图(标题)。
在启用 VoiceOver 的情况下导航时,单元格会按正确的顺序读取(标题、collectionviewcell1、collectionviewcell2...),但是,在视图滚动后(由于在单元格中从左向右滑动而导致),顺序会被破坏,读出UICollectionView 单元格,然后是标题。
这可能是什么原因造成的?
我尝试在包含的 UITableViewCell 上使用 UIAccessibilityContainer 协议,并返回 UICollectionView 中的项目数和标头,以及返回索引 0 处的标头和给定索引处的 UICollectionViewCell 的索引。这总是首先突出显示标题,但不会浏览 UICollectionView 单元格。
我还尝试将计数返回为 2 个元素(header 和 UICollectionView),并返回这些对象作为accessibilityElementAtIndex。这确实从标题开始,但只读出 CollectionView 中的第一项
事实证明,错误的排序是由于使用 UITableViewCell 作为 UICollectionView 的标题视图造成的。在打开 VoiceOver 的情况下滚动时出现崩溃,我设法通过返回 UIAccessibilityContainer 协议中单元格的 contentView 来阻止此崩溃。
#pragma mark - UIAccessibilityContainer
-(NSInteger)accessibilityElementCount {
int headerCount = self.headerView ? 1 : 0;
int footerCount = self.footerView ? 1 : 0;
return ([self.dataValues count] + headerCount + footerCount;
}
-(id)accessibilityElementAtIndex:(NSInteger)index {
if (index == 0) {
if (self.headerView) {
if ([self.headerView isKindOfClass:[UITableViewCell class]]) {
UIView *header = ((UITableViewCell *)self.headerView).contentView;
header.shouldGroupAccessibilityChildren = YES;
return header;
}
return self.headerView;
}
}
if (self.headerView) index -= 1;
if (index >= [self.dataValues count]) {
if ([self.footerView isKindOfClass:[UITableViewCell class]]) {
return ((UITableViewCell *)self.footerView).contentView;
}
return self.footerView;
}
return [self collectionView:_collectionView cellForItemAtIndexPath:[NSIndexPath indexPathForRow:index inSection:0]];
}
这个问题的答案为我指明了正确的方向:
Swift 版本解决方案已在 iOS 11 上测试。
override func accessibilityElementCount() -> Int {
return cellViewModels.count
}
override func accessibilityElement(at index: Int) -> Any? {
return collectionView.cellForItem(at: IndexPath(item: index, section: 0))
}
override func accessibilityElementCount() -> Int {
return data.count
}
override func accessibilityElement(at index: Int) -> Any? {
return collectionView.cellForItem(at: IndexPath(item: index, section: 0))
}