Swift 3:如何将 UICollectionView 中的最后一行单元格水平居中,只有一个部分? [英] Swift 3: How to center horizontally the last row of cells in a UICollectionView with only one section?

查看:44
本文介绍了Swift 3:如何将 UICollectionView 中的最后一行单元格水平居中,只有一个部分?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用只有一个部分的 UICollectionView.这是一些可视化:

I'm using a UICollectionView with only one section. Here's some visualization:

[ x x x ]  
[ x x x ]  
[ x x   ] 

如果 UICollectionView 中的最后一行没有填充所有 3 个单元格,我想像这样将这些单元格居中:

If the last row in the UICollectionView does not have all 3 cells filled, I'd like to center those cells like so:

[ x x x ]  
[ x x x ]  
[  x x  ] 

我尝试从以下地方实施解决方案:

I've tried to implement solutions from the following places:

  1. 如何水平居中 UICollectionView 单元格?

如何居中对齐UICollectionView?

但是,解决方案会移动所有单元格,如果最后一行不包含 X 个单元格,我只想移动最后一行,因为我只有一个部分.

However, the solutions shifts all the cells, and I'd like to only shift the LAST row if that last row doesn't contain X number of cells since I only have one section.

我知道如何设置插图,但我不知道如何通过只有一个部分并尝试调整最后一行单元格的插图来实现这一点.

I know how to set insets, but I don't know how to achieve this with being only one section and trying to adjust the inset on the last row of cells.

我刚开始使用 UICollectionView 不知道如何解决这个问题?

I just started using UICollectionView and not sure how to go around this issue?

推荐答案

听起来您需要流布局提供的所有内容,并进行一些自定义.子类化流布局和覆盖 layoutAttributesForElements 应该可以完成这项工作:

Sounds like you need everything a flow layout offers with a little customizations. Subclassing flow layout and overriding layoutAttributesForElements should do the job:

一个快速而肮脏的实现基本上会要求 FlowLayout 为给定的矩形进行布局,然后找出最后一行出现的项目.如果少于 3 个项目,则将它们均匀地隔开.

A quick and dirty implementation will basically ask FlowLayout to do the layout for a given rect, then figure out what items appear in the last row. If there are less than 3 items, then space them out evenly.

class LastRowCenteredLayout: UICollectionViewFlowLayout {
    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        guard var elementAttributes = super.layoutAttributesForElements(in: rect) else { return nil }
        guard elementAttributes.count > 0 else { return elementAttributes }

        elementAttributes = elementAttributes.map { $0.copy() as! UICollectionViewLayoutAttributes }

        let minY = elementAttributes.last!.frame.minY
        let lastRowAttrs = elementAttributes.reversed().filter { $0.frame.minY == minY }

        guard lastRowAttrs.count < 3,
                let first = elementAttributes.first,
                let last = elementAttributes.last else {
            return elementAttributes
        }

        let horizontalPadding = rect.width - first.frame.minX - last.frame.maxX
        let horizontalShift = horizontalPadding / 2.0

        for attrs in lastRowAttrs {
            attrs.frame = attrs.frame.offsetBy(dx: horizontalShift, dy: 0)
        }

        return elementAttributes
    }
}

请注意,如果您计划对插入/删除进行动画处理,您还应该覆盖 layoutAttributesForCellWithIndexPath: 并确保它返回一致的结果.

Note that if you plan on animating insertions/deletions, you should also override layoutAttributesForCellWithIndexPath: and ensure it returns consistent results.

Apple 有一个指南在 FlowLayout 上有一个专门用于子类化的部分.

Apple has a guide on FlowLayout with a section dedicated to subclassing.

示例游乐场:

https://gist.github.com/AnuragMishra/0a694dfa9be1a5eab9fc7368b69812ad

这篇关于Swift 3:如何将 UICollectionView 中的最后一行单元格水平居中,只有一个部分?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆