У меня есть 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, и после того, как она оживляет переход на новый location:
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
не вызывается на горизонтальном свитке, как я хочу. Тем не менее, он вызывается снова после горизонтальной прокрутки перемещает представление коллекции по вертикали. Большой вопрос здесь заключается в том, почему поведение горизонтальной прокрутки также перемещает представление коллекции вертикально к первоначальному выравниванию?