我正在开发一个tvOS应用程序,我希望collectionView的活动单元始终处于相同的位置。换句话说,我不希望活动单元格通过我的collectionView但我希望collectionView通过我的活动单元格。
以下图片中的示例。活动标签始终位于屏幕的中心,而您可以滚动collectionView以在其上获得不同的活动标签。
基本上是带有自定义UI的选择器视图。但不幸的是,未在tvOS上提供iOS的挑选视图...
我已经调查了UICollectionViewScrollPosition.verticallyCentered
。这部分让我在那里,但它还不够。如果我滚动得非常快,活动项目会在列表中向下跳跃,当我暂停时,它会一直向上滚动到中心。我真的希望活动项目始终位于屏幕的中心。
关于如何做到这一点的任何想法?
根据@HMHero回复
进行更新好的,我试着做你告诉我的事,但不能让滚动工作正常。这可能是由于我计算了偏移量,或者因为(就像你说的那样)setContentOffset(, animated: )
无效。
现在我做了以下事情,不知道从哪里开始;
禁用滚动并居中最后和第一个标签
override func viewDidLoad() {
super.viewDidLoad()
//Disable scrolling
self.collectionView.isScrollEnabled = false
//Place the first and last label in the middle of the screen
self.countryCollectionView.contentInset.top = collectionView.frame.height * 0.5 - 45
self.countryCollectionView.contentInset.bottom = collectionView.frame.height * 0.5 - 45
}
获取标签的位置以检索距屏幕中心的距离(偏移)
func collectionView(_ collectionView: UICollectionView, didUpdateFocusIn context: UICollectionViewFocusUpdateContext, with coordinator: UIFocusAnimationCoordinator) {
if let indexPath = context.nextFocusedIndexPath,
let cell = countryCollectionView.cellForItem(at: indexPath) {
//Get the center of the next focused cell, and convert that to position in the visible part of the (tv) screen itself
let cellCenter = countryCollectionView.convert(cell.center, to: countryCollectionView.superview)
//Get the center of the collectionView
let centerView = countryCollectionView.frame.midY
//Calculate how far the next focused cell y position is from the centerview. (Offset)
let offset = cellCenter.y - centerView
}
}
打印时偏移量返回100的增量值。标签'高度是90,并且间隔为10.所以我认为这是正确的,尽管它一直运行到2400(最后一个标签)。
关于从哪里去的任何想法?
答案 0 :(得分:4)
自从我在tvOS上工作已经一年多了,但是我记得通过一个简单的技巧它应该相当简单。使用更新的api可能有更好的方法来做到这一点,但这就是我所做的。
1)禁用滚动集合视图isScrollEnabled = false
2)在委托中,可选的public func collectionView(_ collectionView:UICollectionView,didUpdateFocusIn context:UICollectionViewFocusUpdateContext,with coordinator:UIFocusAnimationCoordinator),获取nextFocusedIndexPath并计算单元格在集合视图中心的偏移量。
3)使用偏移量,在委托回调中手动设置滚动动画。
我找到了一个老帖子,我知道了。
How to center UICollectionViewCell that was focused?
我最终与线程中的答案有所不同,但这是一个很好的暗示。
答案 1 :(得分:0)
好的,除了@HMHero的一些指示,我已经达到了预期的效果。它涉及使用自定义动画为contentOffset设置动画。这是我的代码;
func collectionView(_ collectionView: UICollectionView, didUpdateFocusIn context: UICollectionViewFocusUpdateContext, with coordinator: UIFocusAnimationCoordinator) {
if let previousIndexPath = context.previouslyFocusedIndexPath,
let cell = countryCollectionView.cellForItem(at: previousIndexPath) {
UIView.animate(withDuration: 0.3, delay: 0, options: UIViewAnimationOptions.curveEaseOut, animations: {
cell.contentView.alpha = 0.3
cell.contentView.transform = CGAffineTransform(scaleX: 0.7, y: 0.7)
})
}
if let indexPath = context.nextFocusedIndexPath,
let cell = countryCollectionView.cellForItem(at: indexPath) {
let cellCenter = CGPoint(x: cell.bounds.origin.x + cell.bounds.size.width / 2, y: cell.bounds.origin.y + cell.bounds.size.height / 2)
let cellLocation = cell.convert(cellCenter, to: self.countryCollectionView)
let centerView = countryCollectionView.frame.midY
let contentYOffset = cellLocation.y - centerView
UIView.animate(withDuration: 0.3, delay: 0, options: UIViewAnimationOptions.curveEaseOut, animations: {
collectionView.contentOffset.y = contentYOffset
cell.contentView.alpha = 1.0
cell.contentView.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
self.countryCollectionView.layoutIfNeeded()
})
}
}