当 VoiceOver 打开时,我的 UICollectionView 没有填充任何单元格
My UICollectionView doesn't get populated with any cells when VoiceOver is on
我在 iOS 13.
中遇到了一个特殊的辅助功能问题
我有一个实现为 UICollectionView 的日历。如果打开 VoiceOver,collection 视图是空的 - 它根本不会填充任何 UICollectionViewCells。
我已经覆盖了正确的 UICollectionViewDataSource 调用。 numberOfSections
和 collectionView(numberOfItemsInSection)
被调用,returns 更正非零值。但是 collectionView(cellForItemAt)
永远不会被调用。那对我来说没有任何意义;它知道我有多少栏目,有多少物品,但它不关心询问物品。
如果我关闭 VoiceOver,它会调用 collectionView(cellForItemAt)
并正确填充我的 collection 视图。在 iOS 12 中,无论 VoiceOver 是否打开,一切都正常。
我错过了什么,或者我该如何调试它? VoiceOver 的状态如何影响我的 collection 视图是否被填充?
我们向 Apple 代表报告了该问题并得到了回复。发生的事情是,在 iOS 13 中,VoiceOver 向集合视图询问有关比可见矩形更大的信息;这是一项有意的更改,以支持某些类型的集合视图,其内容大小事先未知。所以它调用了我们对 layoutAttributesForElements(in rect:)
的覆盖,其中矩形的 Y 值很大,我们没有任何元素。
我们的解决方法是忽略给定矩形的 Y 值,而是使用 0
的 Y 值。 iOS 然后能够找到我们的集合视图单元格。
我遇到了完全相同的问题,但是 Brian 的回答对我不起作用。相反,我发现是将 UICollectionView 的委托和数据源设置为 nil 导致了这个问题。删除将其设置为 nil 的行修复了它。
我遇到了这个问题(UICollectionView 正常,但打开 VoiceOver 时空白)并且无法在任何地方找到答案(none 我遇到问题的已发布回复)。
我的问题原来是针对垂直 UICollectionView 的,您可以将 contentSize 设置为 (width:0, height:something)
,并且效果很好。但是使用 VoiceOver 它真的不喜欢那样 width:0
并且不会尝试加载任何东西。修复方法是将宽度设置为任意值,甚至 width:1
,突然它会再次开始工作。
iOS 14.2 上的问题(未测试其他 iOS 版本)
看起来苹果出于某种原因将用于 layoutAttributesForElements(in rect: CGRect) 的原点设置为负设备高度。我通过使用规范化代码解决了这个问题。
func normalizeRect(_ rect: CGRect) -> CGRect {
guard rect.origin.x < 0, rect.origin.y < 0 else { return rect }
let normalizedSize = CGSize(width: rect.origin.x + rect.width, height: rect.origin.y + rect.height)
let value = CGRect(origin: .zero, size: normalizedSize)
return value
}
Example iPhone 12max:
* expected rect (0.0, 0.0, 428.0, 926.0)
* given rect (-926.0, -926.0, 1354.0, 2778.0)
* normalized rect: (0, 0, 428 (-926 + 1354), 1852 (-926 + 2278 == 2 * 926))
我遇到了同样的问题,但是之前发布的规范化传入 layoutAttributesForElements(in rect: CGRect)
的矩形的解决方案不起作用(事实上,我们甚至根本没有使用传入的矩形值 --我们实现中的方法签名是 layoutAttributesForElements(in _: CGRect)
),也没有像 Kyle 建议的那样直接在 collectionView 上设置 contentSize。
对我来说解决问题的方法是覆盖 UICollectionViewLayout
子类上的 collectionViewContentSize
计算 属性。显然,此方法默认配置为 return .zero
,这会在启用画外音时破坏布局。仍在努力弄清楚为什么会发生这种情况,但同时将以下内容添加到 UICollectionViewLayout
子类中解决了问题:
override var collectionViewContentSize: CGSize {
guard let collectionView = collectionView else { return .zero }
return collectionView.frame.size
}
我在 iOS 13.
中遇到了一个特殊的辅助功能问题我有一个实现为 UICollectionView 的日历。如果打开 VoiceOver,collection 视图是空的 - 它根本不会填充任何 UICollectionViewCells。
我已经覆盖了正确的 UICollectionViewDataSource 调用。 numberOfSections
和 collectionView(numberOfItemsInSection)
被调用,returns 更正非零值。但是 collectionView(cellForItemAt)
永远不会被调用。那对我来说没有任何意义;它知道我有多少栏目,有多少物品,但它不关心询问物品。
如果我关闭 VoiceOver,它会调用 collectionView(cellForItemAt)
并正确填充我的 collection 视图。在 iOS 12 中,无论 VoiceOver 是否打开,一切都正常。
我错过了什么,或者我该如何调试它? VoiceOver 的状态如何影响我的 collection 视图是否被填充?
我们向 Apple 代表报告了该问题并得到了回复。发生的事情是,在 iOS 13 中,VoiceOver 向集合视图询问有关比可见矩形更大的信息;这是一项有意的更改,以支持某些类型的集合视图,其内容大小事先未知。所以它调用了我们对 layoutAttributesForElements(in rect:)
的覆盖,其中矩形的 Y 值很大,我们没有任何元素。
我们的解决方法是忽略给定矩形的 Y 值,而是使用 0
的 Y 值。 iOS 然后能够找到我们的集合视图单元格。
我遇到了完全相同的问题,但是 Brian 的回答对我不起作用。相反,我发现是将 UICollectionView 的委托和数据源设置为 nil 导致了这个问题。删除将其设置为 nil 的行修复了它。
我遇到了这个问题(UICollectionView 正常,但打开 VoiceOver 时空白)并且无法在任何地方找到答案(none 我遇到问题的已发布回复)。
我的问题原来是针对垂直 UICollectionView 的,您可以将 contentSize 设置为 (width:0, height:something)
,并且效果很好。但是使用 VoiceOver 它真的不喜欢那样 width:0
并且不会尝试加载任何东西。修复方法是将宽度设置为任意值,甚至 width:1
,突然它会再次开始工作。
iOS 14.2 上的问题(未测试其他 iOS 版本)
看起来苹果出于某种原因将用于 layoutAttributesForElements(in rect: CGRect) 的原点设置为负设备高度。我通过使用规范化代码解决了这个问题。
func normalizeRect(_ rect: CGRect) -> CGRect {
guard rect.origin.x < 0, rect.origin.y < 0 else { return rect }
let normalizedSize = CGSize(width: rect.origin.x + rect.width, height: rect.origin.y + rect.height)
let value = CGRect(origin: .zero, size: normalizedSize)
return value
}
Example iPhone 12max:
* expected rect (0.0, 0.0, 428.0, 926.0)
* given rect (-926.0, -926.0, 1354.0, 2778.0)
* normalized rect: (0, 0, 428 (-926 + 1354), 1852 (-926 + 2278 == 2 * 926))
我遇到了同样的问题,但是之前发布的规范化传入 layoutAttributesForElements(in rect: CGRect)
的矩形的解决方案不起作用(事实上,我们甚至根本没有使用传入的矩形值 --我们实现中的方法签名是 layoutAttributesForElements(in _: CGRect)
),也没有像 Kyle 建议的那样直接在 collectionView 上设置 contentSize。
对我来说解决问题的方法是覆盖 UICollectionViewLayout
子类上的 collectionViewContentSize
计算 属性。显然,此方法默认配置为 return .zero
,这会在启用画外音时破坏布局。仍在努力弄清楚为什么会发生这种情况,但同时将以下内容添加到 UICollectionViewLayout
子类中解决了问题:
override var collectionViewContentSize: CGSize {
guard let collectionView = collectionView else { return .zero }
return collectionView.frame.size
}