【问题标题】:Make collectionView scrolls as AppStore games section将 collectionView 滚动为 AppStore 游戏部分
【发布时间】:2018-02-26 09:42:19
【问题描述】:

我有一个启用了水平滚动方向和分页的 collectionView,现在我想让它像 AppStore 上的游戏部分一样流畅地滚动。

更具体地说,这是我希望第一个单元格的样子:

编辑

我实际上实现了下两张图片,其中一张宽度较小 的单元格和下一个与 selectItem 中的 .centeredHorizo​​ntally, 我的问题是滚动不顺畅。

如您所见,出现了第二个单元格。

这是下一个单元格:

你现在可以看到上一个和下一个单元格出现了。

我通过设置这部分代码设法做到了这一点,但弹跳不如 AppStore 顺利。

这是我使用的代码:

       func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
            var visibleRect = CGRect()

            visibleRect.origin = collectionView.contentOffset
            visibleRect.size = collectionView.bounds.size

            let visiblePoint = CGPoint(x: visibleRect.midX, y: visibleRect.midY)

            let visibleIndexPath: IndexPath = collectionView.indexPathForItem(at: visiblePoint) ?? IndexPath()
            let indexPath = IndexPath(item: visibleIndexPath[1], section: 0)
            collectionView.selectItem(at: indexPath, animated: true, scrollPosition: .centeredHorizontally )

        }

这是我的 collectionView 代码:

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

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

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

        let frameSize = collectionView.frame.size
        return CGSize(width: frameSize.width - 30, height: frameSize.height - 40)
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
        return UIEdgeInsets(top: 0, left: 0, bottom: 20, right: 0)
    }

【问题讨论】:

  • 要看到第二个单元格的一点点出现,设置单元格的大小比集合视图宽度小一点。
  • @pkc456 对不起,我忘了提,我已经通过使单元格的宽度比collectionView小一点来实现这一点
  • 我的问题是当我在稳定之前左右滚动时

标签: ios swift uicollectionview app-store


【解决方案1】:

Example project here

在类属性中

     var itemSize = CGSize(width: 0, height: 0)
     @IBOutlet weak var collectionViewHeight: NSLayoutConstraint!
     @IBOutlet weak var collectionView: UICollectionView!
     fileprivate let sectionInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)

在 viewDidLoad 或 awakeFormNib 中(如果在 collectionViewCell 或 tableViewCell 中)

    if let layout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
        layout.minimumLineSpacing = 0
        layout.minimumInteritemSpacing = 0
    }
    collectionView.contentInset = UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 8)
    collectionView.isPagingEnabled = false
    layoutIfNeeded()

    let width = collectionView.bounds.size.width-24
    let height = width * (3/4)
    itemSize = CGSize(width: width, height: height)
    layoutIfNeeded()

实现 UICollectionViewDelegateFlowLayout

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

        return sectionInsets
    }

    func collectionView(_ collectionView: UICollectionView,
                    layout collectionViewLayout: UICollectionViewLayout,
                    sizeForItemAt indexPath: IndexPath) -> CGSize {
        return itemSize
    }

实现 ScrollViewDelegate

func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
    let pageWidth = itemSize.width
    targetContentOffset.pointee = scrollView.contentOffset
    var factor: CGFloat = 0.5
    if velocity.x < 0 {
        factor = -factor
        print("right")
    } else {
        print("left")
    }

    let a:CGFloat = scrollView.contentOffset.x/pageWidth
    var index = Int( round(a+factor) )
    if index < 0 {
        index = 0
    }
    if index > collectionViewDataList.count-1 {
        index = collectionViewDataList.count-1
    }
    let indexPath = IndexPath(row: index, section: 0)
    collectionView?.scrollToItem(at: indexPath, at: .left, animated: true)
}

在过去的游乐设施部分查看我的项目的示例屏幕截图 我在collectionViewCell中实现了uicollectionview

【讨论】:

  • 谢谢你的回答,我会查的
  • 我检查了它,我遇到了一个问题,就像我制作的那个一样......当我滚动时,如果我点击单元格(在滚动停止之前)滚动停止。
  • 我会尝试解决这种情况。
  • 只需在func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)中添加collectionView.scrollToItem(at: indexPath, at: .left, animated: false)
  • 完美!谢谢
【解决方案2】:

设置 collectionView?.isPagingEnabled = true 并删除您的 scrollViewDidEndDecelerating 方法

【讨论】:

  • 我这样做了,但是第一个单元格之后的每个单元格都不是水平居中的
  • 你把UICollectionViewFlowLayout的滚动方向设置为horizontal了吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-04
  • 2017-01-22
  • 2014-02-04
  • 1970-01-01
  • 1970-01-01
  • 2017-03-02
  • 1970-01-01
相关资源
最近更新 更多