Ios 检测距离collectionview中心最近的collectionviewcell
怀疑我在下面做了一些根本错误的事情。。。我有一个水平集合视图,拖动后,我想捕捉到离中心最近的单元格。但是我的结果是不可预测的。。。我做错了什么Ios 检测距离collectionview中心最近的collectionviewcell,ios,uicollectionview,uicollectionviewcell,Ios,Uicollectionview,Uicollectionviewcell,怀疑我在下面做了一些根本错误的事情。。。我有一个水平集合视图,拖动后,我想捕捉到离中心最近的单元格。但是我的结果是不可预测的。。。我做错了什么 func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) { // Find collectionview cell nearest to the center of collectionView // Arbi
func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) {
// Find collectionview cell nearest to the center of collectionView
// Arbitrarily start with the last cell (as a default)
var closestCell : UICollectionViewCell = collectionView.visibleCells()[0];
for cell in collectionView!.visibleCells() as [UICollectionViewCell] {
let closestCellDelta = abs(closestCell.center.x - collectionView.bounds.size.width/2.0)
let cellDelta = abs(cell.center.x - collectionView.bounds.size.width/2.0)
if (cellDelta < closestCellDelta){
closestCell = cell
}
}
let indexPath = collectionView.indexPathForCell(closestCell)
collectionView.scrollToItemAtIndexPath(indexPath!, atScrollPosition: UICollectionViewScrollPosition.CenteredHorizontally, animated: true)
}
func-scrollViewDiEndDraging(scrollView:UIScrollView,willDecreate-Decreate:Bool){
//查找距离collectionview中心最近的collectionview单元格
//任意从最后一个单元格开始(默认)
var closestCell:UICollectionViewCell=collectionView.visibleCells()[0];
对于collectionView!.visibleCells()中的单元格作为[UICollectionViewCell]{
让closestcelldta=abs(closestCell.center.x-collectionView.bounds.size.width/2.0)
让cellDelta=abs(cell.center.x-collectionView.bounds.size.width/2.0)
if(cellDelta
试试这个:
NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:self.collectionView.center];
[self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:YES];
斯威夫特:
let indexPath = self.collectionView.indexPathForItemAtPoint(self.collectionView.center)
self.collectionView.scrollToItemAtIndexPath(indexPath!, atScrollPosition: UICollectionViewScrollPosition.CenteredHorizontally, animated: true)
由于CollectOnView内容偏移量的原因,我的原始代码丢失了。此外,我已经将居中移动到ScrollViewDiEndDecelling回调中。我修改了原始代码并将其包含在下面
func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
// Find collectionview cell nearest to the center of collectionView
// Arbitrarily start with the last cell (as a default)
var closestCell : UICollectionViewCell = collectionView.visibleCells()[0];
for cell in collectionView!.visibleCells() as [UICollectionViewCell] {
let closestCellDelta = abs(closestCell.center.x - collectionView.bounds.size.width/2.0 - collectionView.contentOffset.x)
let cellDelta = abs(cell.center.x - collectionView.bounds.size.width/2.0 - collectionView.contentOffset.x)
if (cellDelta < closestCellDelta){
closestCell = cell
}
}
let indexPath = collectionView.indexPathForCell(closestCell)
collectionView.scrollToItemAtIndexPath(indexPath!, atScrollPosition: UICollectionViewScrollPosition.CenteredHorizontally, animated: true)
}
func ScrollViewDiEndDecelling(scrollView:UIScrollView){
//查找距离collectionview中心最近的collectionview单元格
//任意从最后一个单元格开始(默认)
var closestCell:UICollectionViewCell=collectionView.visibleCells()[0];
对于collectionView!.visibleCells()中的单元格作为[UICollectionViewCell]{
让closestcelldta=abs(closestCell.center.x-collectionView.bounds.size.width/2.0-collectionView.contentOffset.x)
设cellDelta=abs(cell.center.x-collectionView.bounds.size.width/2.0-collectionView.contentOffset.x)
if(cellDelta
Swift 4的更新版本
var closestCell = collectionView.visibleCells[0]
for cell in collectionView.visibleCells {
let closestCellDelta = abs(closestCell.center.x - collectionView.bounds.size.width/2.0 - collectionView.contentOffset.x)
let cellDelta = abs(cell.center.x - collectionView.bounds.size.width/2.0 - collectionView.contentOffset.x)
if (cellDelta < closestCellDelta){
closestCell = cell
}
}
let indexPath = collectionView.indexPath(for: closestCell)
collectionView.scrollToItem(at: indexPath!, at: .centeredHorizontally, animated: true)
var closestCell=collectionView.visibleCells[0]
对于collectionView.visibleCells中的单元格{
让closestcelldta=abs(closestCell.center.x-collectionView.bounds.size.width/2.0-collectionView.contentOffset.x)
设cellDelta=abs(cell.center.x-collectionView.bounds.size.width/2.0-collectionView.contentOffset.x)
if(cellDelta
- 停止拖动时,只需选择中心并使用它选择索引
没有一个解决方案能可靠地为我工作,所以我写了这篇文章,它在100%的时间里都能工作。很简单。甚至内置的indexPathForItemAtPoint也不能100%工作
extension UICollectionView {
var centerMostCell:UICollectionViewCell? {
guard let superview = superview else { return nil }
let centerInWindow = superview.convert(center, to: nil)
guard visibleCells.count > 0 else { return nil }
var closestCell:UICollectionViewCell?
for cell in visibleCells {
guard let sv = cell.superview else { continue }
let cellFrameInWindow = sv.convert(cell.frame, to: nil)
if cellFrameInWindow.contains(centerInWindow) {
closestCell = cell
break
}
}
return closestCell
}
}
1:需要确保我们正在将点从superview坐标空间转换为collectionView的空间
2:使用collectionView的局部空间点来查找索引
3:返回indexPath的单元格看起来应该可以,但对我来说,indexPathForItemAtPoint返回nil。总是返回nil吗?或者只是在某些时候?总是。。。这很有趣,也许还有别的事情。如果有机会,我将发布更完整的代码。当点位于单元格之间时,此处建议的解决方案将返回零,因此这对我来说不是一个有效的解决方案。而您确定了itt…;)很接近,但对我来说不是修复。位置1处的单元格始终被跳过,以支持单元格0或2。那是画像。在景观中,倒数第二个单元格也受到了类似的影响。使用了一个符咒,必须更新部分的插图,以允许将第一个和最后一个项目居中。请使用Objective c版本。我在搜索中看到了几个这样的例子,每次都会得到一个scrollViewDidSomething函数,其中引用了“collectionView”。每当我尝试这一点时,我都会得到“collectionView的模糊使用”。您在哪里定义“collectionView”?ScrollViewDiEndDecreating函数是否在另一个允许您引用collectionView的函数中?发布答案后,我意识到如果没有包含collection view中心点的单元格,则返回nil。所以,只要有一个包含中心的单元,你就可以得到它。
extension UICollectionView {
var centerMostCell:UICollectionViewCell? {
guard let superview = superview else { return nil }
let centerInWindow = superview.convert(center, to: nil)
guard visibleCells.count > 0 else { return nil }
var closestCell:UICollectionViewCell?
for cell in visibleCells {
guard let sv = cell.superview else { continue }
let cellFrameInWindow = sv.convert(cell.frame, to: nil)
if cellFrameInWindow.contains(centerInWindow) {
closestCell = cell
break
}
}
return closestCell
}
}
var centerUICollectionViewCell: UICollectionViewCell? {
get {
// 1
guard let center = collectionView.superview?.convert(collectionView.center, to: collectionView) else { return nil }
// 2
guard let centerIndexPath = collectionView.indexPathForItem(at: center) else { return nil }
// 3
return collectionView.cellForItem(at: centerIndexPath)
}
}