如何在Swift3.0中居中对齐UICollectionView的单元格?

kem*_*ica 10 ios swift tvos swift3

描述:

答案Objective-CSwift2.0:如何居中对齐UICollectionView的单元格?

我通常会尝试将Swift2.0答案转换为Swift3.0解决方案,但方法是:

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int) -> UIEdgeInsets {
        let edgeInsets = (screenWight - (CGFloat(elements.count) * 50) - (CGFloat(elements.count) * 10)) / 2
        return UIEdgeInsetsMake(0, edgeInsets, 0, 0);
    }
Run Code Online (Sandbox Code Playgroud)

似乎不存在Swift3.0,我找到的唯一有用的方法似乎是:

func collectionView(_ collectionView: UICollectionView, transitionLayoutForOldLayout fromLayout: UICollectionViewLayout, newLayout toLayout: UICollectionViewLayout) -> UICollectionViewTransitionLayout {
        <#code#>
}
Run Code Online (Sandbox Code Playgroud)

但我不确定如何正确实施它.

题:

如何对准一个UICollectionViewin 的细胞Swift3.0

(iOS和tvOS的简单通用解决方案将是完美的)

kem*_*ica 17

这最终成为我使用的解决方案.阅读代码注释以便更好地理解.Swift 3.0

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

        //Where elements_count is the count of all your items in that
        //Collection view...
        let cellCount = CGFloat(elements_count)

        //If the cell count is zero, there is no point in calculating anything.
        if cellCount > 0 {
            let flowLayout = collectionViewLayout as! UICollectionViewFlowLayout
            let cellWidth = flowLayout.itemSize.width + flowLayout.minimumInteritemSpacing

            //20.00 was just extra spacing I wanted to add to my cell.
            let totalCellWidth = cellWidth*cellCount + 20.00 * (cellCount-1)
            let contentWidth = collectionView.frame.size.width - collectionView.contentInset.left - collectionView.contentInset.right

            if (totalCellWidth < contentWidth) {
                //If the number of cells that exists take up less room than the 
                //collection view width... then there is an actual point to centering them.

                //Calculate the right amount of padding to center the cells.
                let padding = (contentWidth - totalCellWidth) / 2.0
                return UIEdgeInsetsMake(0, padding, 0, padding)
            } else {
                //Pretty much if the number of cells that exist take up
                //more room than the actual collectionView width, there is no
                // point in trying to center them. So we leave the default behavior.
                return UIEdgeInsetsMake(0, 40, 0, 40)
            }
        }

        return UIEdgeInsets.zero
    }
Run Code Online (Sandbox Code Playgroud)

  • 我解决了这正是(swift 4),编译,但单元格不在屏幕上居中? (2认同)

jbo*_*ziz 17

虽然rottenoats答案很好,但它有一个额外的间距错误,并没有使用很多可用的swift 3语法.我已经解决了这个问题并减少了对局部变量的依赖数量.

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

    // Make sure that the number of items is worth the computing effort.
    guard let flowLayout = collectionViewLayout as? UICollectionViewFlowLayout,
        let dataSourceCount = collectionView.dataSource?.collectionView(collectionView, numberOfItemsInSection: section),
        dataSourceCount > 0 else {
            return .zero
    }


    let cellCount = CGFloat(dataSourceCount)
    let itemSpacing = flowLayout.minimumInteritemSpacing
    let cellWidth = flowLayout.itemSize.width + itemSpacing
    var insets = flowLayout.sectionInset


    // Make sure to remove the last item spacing or it will
    // miscalculate the actual total width.
    let totalCellWidth = (cellWidth * cellCount) - itemSpacing
    let contentWidth = collectionView.frame.size.width - collectionView.contentInset.left - collectionView.contentInset.right


    // If the number of cells that exist take up less room than the
    // collection view width, then center the content with the appropriate insets.
    // Otherwise return the default layout inset.
    guard totalCellWidth < contentWidth else {
        return insets
    }


    // Calculate the right amount of padding to center the cells.
    let padding = (contentWidth - totalCellWidth) / 2.0
    insets.left = padding
    insets.right = padding
    return insets
}
Run Code Online (Sandbox Code Playgroud)

注意:此代码段仅适用于水平滚动,但可以轻松调整.


mm2*_*282 7

@rottenoats的轻微改编回答.这更通用.

最重要的是要记住让视图控制器符合UICollectionViewDelegateFlowLayout协议.

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

    guard let flowLayout = collectionViewLayout as? UICollectionViewFlowLayout else {
        return .zero
    }

    let cellCount = CGFloat(collectionView.numberOfItems(inSection: section))

    if cellCount > 0 {
        let cellWidth = flowLayout.itemSize.width + flowLayout.minimumInteritemSpacing

        let totalCellWidth = cellWidth * cellCount
        let contentWidth = collectionView.frame.size.width - collectionView.contentInset.left - collectionView.contentInset.right - flowLayout.headerReferenceSize.width - flowLayout.footerReferenceSize.width

        if (totalCellWidth < contentWidth) {
            let padding = (contentWidth - totalCellWidth + flowLayout.minimumInteritemSpacing) / 2.0
            return UIEdgeInsetsMake(0, padding, 0, 0)
        }
    }

    return .zero
}
Run Code Online (Sandbox Code Playgroud)