启用分页时,将一个可水平滚动的集合视图的单元格居中,并使其他单元格也部分可见

提格兰·伊斯坎达良

我有一个水平滚动的收藏夹视图。它上面有几个单元格。已对该集合视图启用分页。

我想让它从居中单元格的左侧和右侧显示单元格的一部分(当它不是第一个或最后一个时),如下所示:

在此处输入图片说明

这是以下代码UICollectionViewDelegateFlowLayout

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize(width: collectionView.frame.width - 50, height: collectionView.frame.height - 16)
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {

    return sectionInsets
}


func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
    return 10
}

并且sectionInsets是以下内容:

 private var sectionInsets = UIEdgeInsetsMake(8, 20, 8, 20)

当前,当我向右滚动时,右边的单元格越来越可见(单元格之间的间隔线向左边缘移动)

我尝试根据此处此处的答案使用不同的值,但无法达到我想要的效果。

如果您对此有任何建议,我们将不胜感激。

提格兰·伊斯坎达良

实际上,解决方案并不难。由于文章,显示了正确的方式来实现此功能,我终于实现了它。

要了解的主要内容是,建立在集合视图中的分页在这种情况下不起作用,因为单元格的大小小于屏幕的大小。因此,我们需要实现我们的自定义分页技术。

首先,在自定义助手中struct,我们定义一个属性,该属性将在拖动之前保存单元格的索引:

var indexOfCellBeforeDragging: Int = 0

然后,我们创建一种用于计算单元格的部分插图的方法:

 //Setting the inset
func calculateSectionInset(forCollectionViewLayout collectionViewLayout: UICollectionViewFlowLayout, numberOfCells: Int) -> CGFloat {
    let inset = (collectionViewLayout.collectionView!.frame.width) / CGFloat(numberOfCells)
    return inset
}

现在我们可以使用上面的方法来设置集合视图的项目大小。

  //Setting the item size of the collection view
func configureCollectionViewLayoutItemSize(forCollectionViewLayout collectionViewLayout: UICollectionViewFlowLayout) {

    let inset: CGFloat = calculateSectionInset(forCollectionViewLayout: collectionViewLayout, numberOfCells: 5)

    collectionViewLayout.sectionInset = UIEdgeInsets(top: 0, left: inset/4, bottom: 0, right: inset/4)

    collectionViewLayout.itemSize = CGSize(width: collectionViewLayout.collectionView!.frame.size.width - inset / 2, height: collectionViewLayout.collectionView!.frame.size.height)
    collectionViewLayout.collectionView?.reloadData()
}

我们需要获取主要单元格(当前最大的单元格)的索引。为此,我们contentOffsetx轴上使用有关项目宽度和集合视图的信息

//Getting the index of the major cell
func indexOfMajorCell(in collectionViewLayout: UICollectionViewFlowLayout) -> Int {
    let itemWidth = collectionViewLayout.itemSize.width
    let proportionalLayout = collectionViewLayout.collectionView!.contentOffset.x / itemWidth
    return Int(round(proportionalLayout))
}

接下来,我们使用上述方法在开始拖动之前设置单元格的索引:

 //Setting the index of cell before starting dragging
mutating func setIndexOfCellBeforeStartingDragging(indexOfMajorCell: Int) {
    indexOfCellBeforeDragging = indexOfMajorCell
}

现在我们应该处理拖动的结束。此外,我们还要注意单元格上可能发生的弹起手势。在此,我们使用一些自定义阈值作为滑动速度。

  //Handling dragging end of a scroll view
func handleDraggingWillEndForScrollView(_ scrollView: UIScrollView, inside collectionViewLayout: UICollectionViewFlowLayout, withVelocity velocity: CGPoint, usingIndexOfMajorCell indexOfMajorCell: Int) {

    //Calculating where scroll view should snap
    let indexOfMajorCell = indexOfMajorCell

    let swipeVelocityThreshold: CGFloat = 0.5

    let majorCellIsTheCellBeforeDragging = indexOfMajorCell == indexOfCellBeforeDragging
    let hasEnoughVelocityToSlideToTheNextCell = indexOfCellBeforeDragging + 1 < 5 && velocity.x > swipeVelocityThreshold
    let hasEnoughVelocityToSlideToThePreviousCell = ((indexOfCellBeforeDragging - 1) >= 0) && (velocity.x < -swipeVelocityThreshold)

    let didUseSwipeToSkipCell = majorCellIsTheCellBeforeDragging && (hasEnoughVelocityToSlideToTheNextCell || hasEnoughVelocityToSlideToThePreviousCell)

    if didUseSwipeToSkipCell {

        let snapToIndex = indexOfCellBeforeDragging + (hasEnoughVelocityToSlideToTheNextCell ? 1 : -1)
        let toValue = collectionViewLayout.itemSize.width * CGFloat(snapToIndex)

        // Damping equal 1 => no oscillations => decay animation
        UIView.animate(withDuration: 0.3, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: velocity.x, options: .allowUserInteraction, animations: {
            scrollView.contentOffset = CGPoint(x: toValue, y: 0)
            scrollView.layoutIfNeeded()
        }, completion: nil)

    } else {
        let indexPath = IndexPath(row: indexOfMajorCell, section: 0)
        collectionViewLayout.collectionView!.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
    }
}

现在,在您的view controller insidescrollViewWillBeginDragging(_:)方法中,我们需要获取主单元格的索引并将其设置为索引,然后再开始拖动(commentsPagingHelper是helper结构的一个实例):

  func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {

    let indexOfMajorCell = commentsPagingHelper.indexOfMajorCell(in: collectionViewLayout)
    commentsPagingHelper.setIndexOfCellBeforeStartingDragging(indexOfMajorCell: indexOfMajorCell)
}

最后,我们处理scrollViewWillEndDragging(_:, withVelocity:, targetContentOffset:)方法中主要单元格索引的更改

 func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {

    //Stop scrollView sliding:
    targetContentOffset.pointee = scrollView.contentOffset


    let indexOfMajorCell = commentsPagingHelper.indexOfMajorCell(in: collectionViewLayout)

    commentsPagingHelper.handleDraggingWillEndForScrollView(scrollView, inside: collectionViewLayout, withVelocity: velocity, usingIndexOfMajorCell: indexOfMajorCell)
}

而已。希望这会对遇到类似问题的人有所帮助。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

水平滚动收集视图在初始加载时部分隐藏了第一个单元格内容

滚动后在UITableView顶部的第一个可见单元格上色

将集合视图中的单元格移到另一部分的最后一个单元格之外不起作用

带有一个可见单元格的UITableView:确定最可见的单元格

查找一个单元格值并根据该单元格的值填充其他单元格

在集合视图中一次滚动一个单元格

UICollectionview userinteraction禁用第一个单元格,同时在滚动时禁用其他几个单元格

If语句根据其他单元格填充一个单元格

第一个单元格比其他单元格宽的表格

一个单元格用数据填充其他单元格

Vlookup一个包含其他单元格但不直接的单元格

根据其他单元格的值增加一个单元格的值

在编辑另一个单元格时填充其他单元格

将最后一个值复制到其他单元格,直到看到填充的单元格

根据其他匹配的单元格将值复制到一个单元格中

集合视图 - 如何在每个部分中仅选择一个单元格

无法使用可滚动单元格将表格单元格内容居中

冻结/浮动单元格,同时保持其他单元格可滚动

滚动时,集合视图单元格重复

需要一个公式来将一个常数单元格与其他单元格进行比较,并从第三个单元格返回一个值

选择单元格时如何自动将CollectionViewCell滚动到最近的单元格(上一个或下一个)

用excel在一个单元格中列出N个其他单元格中的常用值

布局:需要一个可以比同一行中其他单元格更大的单元格

当我对上一个单元格执行某些操作并移动到下一个单元格时更新集合视图单元格的标签

如何部分匹配单元格与另一个部分单元格

UITableView:突出显示最后一个单元格,但其他单元格也突出显示

Visual Basic Msgbox检查一个单元格是否是其他单元格的倍数?

是否可以仅设置一个单元格的宽度而不影响phpExcel中的其他单元格?

如何在Excel中制作一个单元格以根据其他单元格的值更改颜色?