我正在尝试在tvOS上的UITableViewCell中创建一个可水平滚动的UICollectionView,并且已经实现了我的目标。
下一步,我需要将焦点移到UICollectionView中的下一个项目,但是整个项目堆栈应向左或向右移动一个位置,但是焦点将保持在视觉上是“第一项”。
下面是我希望实现的一些ASCII图:
Scenario 1, before focus shifts
---------------------
1. | v v v v v |
2. |[v] v v v v |
3. | v v v v v |
---------------------
Scenario 1, after focus shifts
---------------------
1. | v v v v v |
2. | v [v] v v v |
3. | v v v v v |
---------------------
上面的方案1 是默认的行为,焦点转移到UICollectionView中的下一项。
Scenario 2, before focus shifts
---------------------
1. | v v v v v |
2. |[v] v v v v |
3. | v v v v v |
---------------------
Scenario 2, after focus shifts
---------------------
1. | v v v v v |
2. v |[v] v v v |
3. | v v v v v |
---------------------
在方案2 中,我在遥控器上滑动以选择UICollectionView中的下一个项目之后,焦点应保持在左侧,但焦点下方的项目应移动一个。
>有人对如何实现这一目标有任何暗示吗?
我已经阅读了UICollectionView中粘性列上的帖子,但是我认为这不完全是粘性列吗?
答案 0 :(得分:0)
最近我不得不为此做一个项目。这是我用的:
override func didUpdateFocus(in context: UIFocusUpdateContext, with coordinator: UIFocusAnimationCoordinator) {
if let focusView = context.nextFocusedView as? UICollectionViewCell, let indexPath = collection.indexPath(for: focusView) {
collection.isScrollEnabled = false
coordinator.addCoordinatedAnimations({
self.collection.scrollToItem(at: indexPath, at: .left, animated: true)
}, completion: nil)
}
}
答案 1 :(得分:0)
从 tvOS 13 开始,您可以使用 UICollectionViewCompositionalLayout 的 UICollectionLayoutSectionOrthogonalScrollingBehavior(.groupPagin) 来处理水平滚动的静态焦点。 只需在组中添加一项即可!
private func createCollectionViewLayout() -> UICollectionViewLayout {
let sectionProvider = {
(sectionIndex: Int, layoutEnvironment: NSCollectionLayoutEnvironment) -> NSCollectionLayoutSection? in
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalHeight(1.0))
let item = NSCollectionLayoutItem(layoutSize: itemSize)
let groupSize = NSCollectionLayoutSize(widthDimension: .absolute(100), heightDimension: .absolute(100))
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
let section = NSCollectionLayoutSection(group: group)
section.orthogonalScrollingBehavior = .groupPaging
return section
}
return UICollectionViewCompositionalLayout(sectionProvider: sectionProvider)
}
答案 2 :(得分:0)
UICollectionViewDelegate
方法在焦点移动期间调用。因此,要解决您的任务,您需要操作 UICollectionView 的 (UIScrollView) 内容偏移量。要实现类似“本机”的方式,您需要:
实现UICollectionViewDelegate
方法collectionView:didUpdateFocusInContext:withAnimationCoordiantor
,保存下一个聚焦单元格origin(x,y),并在UIScrollViewDelegate
方法scrollViewWillEndDragging:withVelocity:targetContentOffset:
中设置新目标指向焦点单元格原点的内容偏移量。
@interface CLViewController () <UICollectionViewDelegate, UICollectionViewDataSource>
@property (nonatomic) CGPoint focusedCellPosition;
@end
@implementation CLViewController
- (void)collectionView:(UICollectionView *)collectionView didUpdateFocusInContext:(UICollectionViewFocusUpdateContext *)context withAnimationCoordinator:(UIFocusAnimationCoordinator *)coordinator {
NSIndexPath *next = context.nextFocusedIndexPath;
self.focusedCellPosition = [collectionView cellForItemAtIndexPath:next].frame.origin;
}
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {
*targetContentOffset = self.focusedCellPosition;
}
@end