Swift 3: How to center horizontally the last row of cells in a UICollectionView with only one section?

混江龙づ霸主 提交于 2019-12-01 06:47:36

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

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

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

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

Sample Playground:

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

The short answer is: you can't, using the provided UICollectionViewFlowLayout by Apple

The longer answer is: You're going to have to create a customer UICollectionViewLayout subclass and place the element yourself. Start by going through this tutorial. Then you should have a better understanding of the inner workings to be able to create your own custom layout.

strong textyou can do this simple calculation in your collectionViewLayout function.

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

    //return itemSize
    let spaceBetweenCell :CGFloat = 0
    let screenWidth = UIScreen.main.bounds.size.width - CGFloat(2 * spaceBetweenCell)
    let totalSpace = spaceBetweenCell * 1.0
    if indexPath.row == categories.count-1 {
      // check if last cell is odd
      if categories.count % 2  == 1 {
        return CGSize(width: screenWidth , height: (screenWidth-totalSpace)/4) // all Width and  same previous height
      }else {
        return itemSize
      }
    }else{
      return itemSize
    }
  }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!