Ios UICollectionViewScroll位置不工作
我有一个collectionview,我正试图通过编程滚动它。问题是,如果要滚动到的单元格在集合视图中可见,它不会滚动到中心。因此,下面的单元格中的图像是项目1。它不会滚动到它,但会滚动到项目1到项目2 我一直在尝试垂直使用UICollectionVieSollPosition.center,但这似乎不起作用Ios UICollectionViewScroll位置不工作,ios,swift,uicollectionview,Ios,Swift,Uicollectionview,我有一个collectionview,我正试图通过编程滚动它。问题是,如果要滚动到的单元格在集合视图中可见,它不会滚动到中心。因此,下面的单元格中的图像是项目1。它不会滚动到它,但会滚动到项目1到项目2 我一直在尝试垂直使用UICollectionVieSollPosition.center,但这似乎不起作用 self.collectionView?.scrollToItem(at: IndexPath(row: 1, section: 0), at: UICollectionViewScrol
self.collectionView?.scrollToItem(at: IndexPath(row: 1, section: 0), at: UICollectionViewScrollPosition.centeredVertically, animated: true)
是否有一种方法可以强制滚动集合中心可见的单元格
首先,您需要找到收藏视图的中心,这是如何做到的:
private func findCenterIndex() -> Int {
let center = self.view.convert(numberCollectionView.center, to: self.numberCollectionView)
let row = numberCollectionView!.indexPathForItem(at: center)?.row
guard let index = row else {
return 0
}
return index
}
然后在您的scrollToItem
下获取行号,它应该可以工作:
collectionView.scrollToItem(at: IndexPath(item: findCenterIndex(), section: 0), at: .centeredVertically, animated: false)
从viewDidLayoutSubviews()调用它。我发现最好的方法是不使用scrollToItem,而是获取索引的CGRect,然后使其可见
let rect = self.collectionView.layoutAttributesForItem(at: IndexPath(row: 5, section: 0))?.frame
self.collectionView.scrollRectToVisible(rect!, animated: false)
如果
itemSize
太小,scrollToItem
无法工作。
siwft
collectionView.contentOffset=偏移量
我使用这个固定的看起来您已经将
UICollectionView
中的第一个单元格垂直居中
我发现,如果我通过UICollectionView
的contentInset
属性添加一个inset来居中第一个单元格,那么它的scrollToItem(at:at:animated:)
方法对于已经可见的单元格也不起作用
但是,如果我通过UICollectionViewFlowLayout
的sectionInset
属性添加一个插入,将第一个单元格居中,则scrollToItem(at:at:animated:)
适用于可见单元格
具体而言,在代码中:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
// Padding needed to allow the first and last cells to be centred vertically.
let insectHeight = (collectionView.bounds.height - collectionViewFlowLayout.itemSize.height) / 2.0
// This way is disabled because scrollToItem doesn't work for visible cells.
// collectionView.contentInset = UIEdgeInsets(top: insectHeight,
// left: 0,
// bottom: insectHeight,
// right: 0)
// This is the way for scrollToItem to work for visible cells.
collectionViewFlowLayout.sectionInset = UIEdgeInsets(top: insectHeight,
left: 0,
bottom: insectHeight,
right: 0)
}
我猜
contentInset
是从uicrollview
继承的一个属性UICollectionView
,而scrollToItem(at:at:animated:)
计算偏移量的方式似乎与uicrollview使用contentInset
的方式不兼容,我试图用0.1s延迟它。就我而言,现在看起来不错:
collectionView.collectionViewLayout.invalidateLayout() //just in case, iOS10 may crash btw.
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
self.collectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
}
更新:
好的,原来我在使用layout.estimatedItemSize
和autolayout
来计算单元格的宽度,这就是我遇到这个问题的原因。
也就是说,对我来说,这是因为CollectionView的动态大小调整
。
在我返回手动计算宽度后,一切正常。(通过使用-collectionView:layout:sizeForItemAt:
)在什么事件上滚动单元格?我使用自定义流布局使单元格缩放和粘滞,因此滚动时,它始终“捕捉”到使用偏移的中心。它一直工作,只是当以编程方式滚动到视图中可见的项目时,它不工作。从服务器获取一组数据后,它从viewDidLoad中滚动。我可以看到这是如何获取中心项目的索引的。我看不出这将如何滚动项目的中心,我不清楚你的意思是什么调用功能下的项目。您认为它应该是indexPath(项:而不是(行:这是返回中心索引的一种优雅方式,但我不知道您的想法,这对您来说很明显,这将如何将索引项目滚动到中心,但我看不到它。此命令将告诉您的集合视图滚动到项目位置。因此,如果您的中心位于项目3,其中您的项目总数为6,则应滚动到it.Voted.对我来说,scrollToItem
没有滚动到我想要的位置,并且存在一些布局问题(有时使用疯狂的单元格重新排列使collectionview重新布局)。这种方法非常可靠。但有人知道为什么吗?在这种情况下,您可能使用自定义的UICollectionViewLayout
。通过调用let rect=self.collectionView.collectionViewLayout.layoutAttributesForItem(位于:indexPathToSelect)?.frame
。滚动可见(indexPath:)当项目远离屏幕时,uicollectionview方法不适合我。这种方法很有效。你节省了我的时间。我尝试了很多方法,这是唯一的解决方案。如前所述,你可以使用DispatchQueue.main.async{/*scrollToItem*/}
,它适合我。