swift - 在 tvOS 上居中 UICollectionView 重点行
问题描述
我的 tvOS 应用程序中有一个UICollectionView
填充了几个UICollectionViewCell
s 的 s,而这些 s 又包含一个UICollectionView
带有它们自己的项目的内部。
容器UICollectionView
垂直滚动,而内部UICollectionView
滚动水平。顶级UICollectionViewCell
s 禁用焦点,并传递到内部 s 中的项目UICollectionView
。
它看起来像这样:
-------------------
| |
| --------------- |
| | xxxx xxxx xx| |
| | xxxx xxxx xx| |
| --------------- |
| |
| --------------- |
| | xxxx xxxx xx| |
| | xxxx xxxx xx| |
| --------------- |
| |
-------------------
我在这里想要实现的是,当焦点出现UICollectionView
在UICollectionView
.
Before centering vertically
-------------------
| 1xxx xxxx xxxx x|
| 1xxx xxxx xxxx x|
| |
| 2xxx xxxx xxxx x|
| 2xxx xxxx xxxx x|
| |
| 3xxx xxxx xxxx x| <-
| 3xxx xxxx xxxx x| <-
| |
| 4xxx xxxx xxxx x|
-------------------
=
After centering vertically
-------------------
| |
| 2xxx xxxx xxxx x|
| 2xxx xxxx xxxx x|
| |
| 3xxx xxxx xxxx x|
| 3xxx xxxx xxxx x|
| |
| 4xxx xxxx xxxx x|
| 4xxx xxxx xxxx x|
| |
-------------------
有没有人对我如何实现这一点有评论/建议?
编辑:基于另一个SO post,我尝试实现以下UICollectionViewDelegate
功能,但它似乎对我不起作用:
func collectionView(_ collectionView: UICollectionView, didUpdateFocusIn context: UICollectionViewFocusUpdateContext, with coordinator: UIFocusAnimationCoordinator) {
if let indexPath = context.nextFocusedIndexPath,
let _ = collectionView.cellForItem(at: indexPath) {
collectionView.contentInset.top = max((collectionView.frame.height - collectionView.contentSize.height) / 2, 0)
}
}
编辑:在下面建议的答案导致一些试验和错误之后,我已经让它与以下代码一起使用:
func collectionView(_ collectionView: UICollectionView, didUpdateFocusIn context: UICollectionViewFocusUpdateContext, with coordinator: UIFocusAnimationCoordinator) {
if let indexPath = context.nextFocusedIndexPath {
collectionView.isScrollEnabled = false
coordinator.addCoordinatedAnimations({
self.collectionView.scrollToItem(at: indexPath, at: .centeredVertically, animated: true)
}, completion: nil)
}
}
解决方案
您可以像这样使用 scrollToItemAtIndexPath 方法:
func collectionView(_ collectionView: UICollectionView, didUpdateFocusIn context: UICollectionViewFocusUpdateContext, with coordinator: UIFocusAnimationCoordinator) {
if let indexPath = context.nextFocusedIndexPath,
let _ = collectionView.cellForItem(at: indexPath) {
self.collectionView.scrollToItem(at: indexPath, at:
.centeredVertically, animated: true)
}
}
已编辑
您必须使用可访问性属性或其他方式从单元格中提取 indexPath,而不是像这样滚动到该 indexPath:
override func didUpdateFocus(in context: UIFocusUpdateContext, with coordinator: UIFocusAnimationCoordinator) {
if let nextCell = context.nextFocusedView as? ScrumCollectionViewCell {
let index = Int(nextCell.accessibilityHint!)!
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { // 2
self.collectionView.scrollToItem(at: IndexPath(item: index, section: 0), at: .centeredVertically, animated: true)
}
}
}
推荐阅读
- java - 服务:AmazonSQS;状态码:403;错误代码:SignatureDoesNotMatch;SQS
- javascript - 如何模拟 navigator.language 进行打字稿单元测试
- r - 有条件地用数字列中的点替换逗号
- php - “路线 [登录] 未定义。” 托管后。laravel 5.7 但在本地主机上工作
- javascript - 如何只为部分用户(30%)使用应用程序?
- json - 根据密钥解组 JSON
- java - Flink 1.7.1 fails to authenticate s3a with core-site.xml
- neo4j - apoc.path.expandConfig() extract (subject)-[object]->(predicate) 三元组
- bash - Finding ffmpeg installed version
- linux - Running a command on Linux/Docker Cluster