我有一个UICollectionView,可以在tvOS下垂直和水平滚动。我想控制每个部分的位置,因此我正在使用setContentOffset
属性进行对齐。这很好用,但是,当水平滚动时,单元格返回到我更新contentOffset
之前的垂直位置。
UICollectionView
的设置:
lazy var singleCollectionView: UICollectionView = {
let cv = UICollectionView(frame: self.view.bounds, collectionViewLayout: self.generateLayout())
cv.delegate = self.singleDelegate
cv.dataSource = self.singleDatasource
cv.remembersLastFocusedIndexPath = true
cv.register(DemandCVCell.self, forCellWithReuseIdentifier: "cvCell")
cv.register(UICollectionReusableView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "header")
cv.register(UICollectionReusableView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionFooter, withReuseIdentifier: "footer")
cv.translatesAutoresizingMaskIntoConstraints = false
return cv
}()
private func generateLayout() -> UICollectionViewLayout {
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.20), heightDimension: .absolute(200))
let tileItem = NSCollectionLayoutItem(layoutSize: itemSize)
tileItem.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: -32, bottom: 0, trailing: 0)
var tileGroup:NSCollectionLayoutGroup!
if showType == .bucket {
let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.03), heightDimension: .absolute(H_THUMB_SIZE.height))
tileGroup = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitem: tileItem, count: 3)
} else {
let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.03), heightDimension: .absolute(H_THUMB_SIZE.height))
tileGroup = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [tileItem])
}
let section = NSCollectionLayoutSection(group: tileGroup)
if showType == .bucket {
section.orthogonalScrollingBehavior = .none
} else {
section.orthogonalScrollingBehavior = .continuous
}
let headerSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .absolute(50.0))
let header = NSCollectionLayoutBoundarySupplementaryItem(layoutSize: headerSize, elementKind: "header", alignment: .topLeading)
let footerSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .absolute(40.0))
let footer = NSCollectionLayoutBoundarySupplementaryItem(layoutSize: footerSize, elementKind: "footer", alignment: .bottomLeading)
footer.contentInsets = NSDirectionalEdgeInsets(top: 10, leading: 0, bottom: 0, trailing: 0)
section.boundarySupplementaryItems = [header,footer]
let layout = UICollectionViewCompositionalLayout(section: section)
return layout
}
在代表中,我正在使用以下函数来告知标准Apple滚动何时完成以及将更改动画化为新位置后的情况:
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
let visibleSection = collectionView.indexPathsForVisibleItems.first!.section
guard visibleSection > 0 else {return}
guard visibleSection < parentVC.topicsArray.count - 1 else {
scrollView.setContentOffset(CGPoint(x: scrollView.contentOffset.x, y: scrollView.contentOffset.y - 85), animated: true)
return
}
scrollView.setContentOffset(CGPoint(x: scrollView.contentOffset.x, y: scrollView.contentOffset.y + 75), animated: true)
}
一切正常,直到我水平滚动。正如我想要的那样,水平滚动条上没有调用scrollViewDidEndDecelarating
。但是,在水平滚动垂直移动collectionview之后,确实会再次调用它。这里的最大问题是,为什么水平滚动行为还会将collectionview垂直移回其原始对齐方式?