将最近的collectionviewcell检测到collectionview的中心

时间:2015-10-01 01:55:37

标签: ios uicollectionview uicollectionviewcell

怀疑我正在做一些根本错误的事情......我有一个水平的集合视图,拖动后我想将最近的单元格捕捉到中心。但我的结果是不可预测的......我在这里做错了什么?

    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)
}

6 个答案:

答案 0 :(得分:9)

原来我的原始代码缺少会计用于collecitonview内容偏移。另外,我已将中心移动到scrollViewDidEndDecelerating回调中。我修改了原始代码并将其包含在下面。

    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)
}

答案 1 :(得分:3)

试试这个:

NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:self.collectionView.center];
[self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:YES];

(SWIFT):

let indexPath = self.collectionView.indexPathForItemAtPoint(self.collectionView.center)
self.collectionView.scrollToItemAtIndexPath(indexPath!, atScrollPosition: UICollectionViewScrollPosition.CenteredHorizontally, animated: true)

答案 2 :(得分:1)

没有一个解决方案对我可靠地起作用,所以我写了这个,并且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
    }
    
}

答案 3 :(得分:0)

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)

答案 4 :(得分:0)

  • 停止拖动时,只需选择中心并使用它选择索引路径
  

迅速4.2

func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
    let indexPath = photoCollectionView.indexPathForItem(at: photoCollectionView.center)
    photoCollectionView.scrollToItemAtIndexPath(indexPath!, atScrollPosition: .centeredHorizontally, animated: true)
}

答案 5 :(得分:0)

<Stack.Screen
  name="Home"
  component={HomeScreen}
  options={({navigation}) => ({
    headerRight: () => (
      <Button
        title="Go to Details"
        onPress={() => {
          /* 1. Navigate to the Details route with params */
          navigation.navigate('Details', {
            itemId: 86,
            otherParam: 'anything you want here',
          });
        }}
      />
    ),
  })
/>

1:需要确保我们将点从超视图坐标空间转换为collectionView的空间

2:使用collectionView的本地空间点找到indexPath

3:返回indexPath的单元格