UICollectionView水平分页并在页面之间留有空隙

19

我正在寻找一种用 UICollectionView 替换本机水平分页的方法。

目前我已经做了以下工作:

let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
layout.itemSize = collectionView.frame.size
layout.minimumLineSpacing = 0
layout.minimumInteritemSpacing = 10

collectionView.setCollectionViewLayout(layout, animated: false)
collectionView.isPagingEnabled = true
collectionView.alwaysBounceVertical = false

这很好运作,我得到了水平翻页的效果。

现在我想在页面之间添加水平空间(就像在UIPageViewController上使用UIPageViewControllerOptionInterPageSpacingKey一样)

到目前为止,我找不到一种方法来添加间距而不破坏翻页效果。 我正在寻找与UIPageViewController相同的行为方式:单元格应填充整个屏幕宽度,并且仅当切换页面时才应显示单元格之间的空间。

2个回答

32

解决方案一:

  1. collectionView.isPagingEnabled = false
  2. 添加minimumLineSpacing作为页面之间的距离
  3. 实现targetContentOffsetForProposedContentOffset:withScrollingVelocity:,将内容偏移量移动到最接近的页面。您可以根据itemSizeminimumLineSpacing进行简单的数学计算来计算页面,但可能需要一些工作才能正确实现。

解决方案二:

  1. collectionView.isPagingEnabled = true
  2. 添加minimumLineSpacing作为页面之间的距离
  3. 分页大小基于collectionView的边界。因此,使collectionView大于屏幕尺寸。例如,如果您的minimumLineSpacing为10,则将collectionView的框架设置为{0,-5,width + 10,height}。
  4. 设置等于minimumLineSpacing的contentInset,以便正确显示第一个和最后一个项目。

2
但这样做会很难复制所有分页行为。 - Eyal
5
谢谢你的提示,我按照你说的方法通过匹配插入量 minimumLineSpacing = 20sectionInset = UIEdgeInsets(top: 0, left: 10, bottom: 0, right: 10) 在CollectionViewLayout中完成了它。 - raulriera
1
这是我想要做的:我有一个带有三个页面的ASPagerNode。我试图在页面之间设置最小行间距为10或20。然后,每个页面都是一个带有3列的ASCollectionNode,我试图在3列之间实现相等的间距。我成功地将3列间隔正确地排列了,但是页面略微向右偏移,我正在努力解决这个问题。 - Kugutsumen

3
  • 默认情况下,UICollectionViewFlowLayout的minimumLineSpacing为10.0。当collectionView的项目被水平填充(itemSize.width = collectionView.bounds.width)并且collectionView启用了分页,大于零的'minimumLineSpacing'将导致意外的性能问题:从第二页开始,每一页都有一个间隙,这个间隙会被页码累加。
  • 似乎我们可以通过'minimumLineSpacing'来扩展collectionView的宽度以解决这个问题。但是实践否定了这个解决方案:当有两页或更多页时,collectionView不会给最后一页‘lineSpacing’,所以它的'contentSize'不足以完全显示这页的内容,这意味着如果'minimumLineSpacing'是10.0,那么最后一页的末尾将超出collectionView的contentSize 10.0。
  • 最终,我使用以下简单的解决方案在每个项目之间插入边距(类似UIScrollView的表现):通过固定值'pageSpacing'(例如10.0)扩展每个collectionViewItem的宽度,并同时扩展collectionView的宽度。不要忘记,当布置collevtionViewCell的子视图时,还有一个额外的间隔,这不是用于显示真正的内容。

这里是用Swift 3.1编写的代码,我相信对您来说很容易理解:

let pageSpacing: CGFloat = 10

class ViewController: UITableViewController {
     override func viewDidLoad() {
        super.viewDidLoad()

        let layout = UICollectionViewFlowLayout()
        layout.itemSize                = CGSize(width: view.frame.width + pageSpacing, height: view.frame.height)
        layout.scrollDirection         = .horizontal
        layout.minimumInteritemSpacing = 0
        layout.minimumLineSpacing      = 0

        let frame = CGRect(x: 0, y: 0, width: view.frame.width + pageSpacing, height: view.frame.height)
        let collectionView = UICollectionView(frame: frame, collectionViewLayout: layout)
        view.addSubview(collectionView)
    }
}

class MyCell: UICollectionViewCell {
    var fullScreenImageView = UIImageView()
    override func layoutSubviews() {
        super.layoutSubviews()
        fullScreenImageView.frame = CGRect(x: 0, y: 0, width: frame.width - pageSpacing, height: frame.height)
    }
}

希望我能帮到您。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接