如何通过自动布局设置集合视图的单元格大小

时间:2016-06-25 04:56:41

标签: swift uicollectionview uicollectionviewcell ios-autolayout

您好我试图通过auto layout调整单元格的大小。

我想用3乘3显示单元格。

第一个Cell的边距= 0

Last Cell的边距= 0

所有小区的空间都是1pt。就像instagram

enter image description here

enter image description here

我应该设置为Cell的尺寸吗?我希望通过Autolayout设置约束。

我还尝试使用代码设置单元格的大小。

这是我的代码:

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
    return CGSizeMake(123, 123);
}

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAtIndex section: Int) -> CGFloat {
    return 1;
}

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAtIndex section: Int) -> CGFloat {
    return 1;
}

但是......我认为不完全计算单元格的大小。

如何根据屏幕尺寸设置手机的大小?

我必须在单元格之间设置1pt的空间。

无论如何只能使用故事板设置?

如果没有,我该如何设置代码?

谢谢。

5 个答案:

答案 0 :(得分:24)

我不相信你只能使用故事板来设置大小,因为你不能设置重复项目的约束,比如在运行时动态创建的集合视图单元格。

您可以根据给定的信息轻松计算尺寸。在collectionView(_:layout:sizeForItemAt:)中,您可以访问collectionView的边界来计算所需的单元格大小:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    // Compute the dimension of a cell for an NxN layout with space S between
    // cells.  Take the collection view's width, subtract (N-1)*S points for
    // the spaces between the cells, and then divide by N to find the final
    // dimension for the cell's width and height.

    let cellsAcross: CGFloat = 3
    let spaceBetweenCells: CGFloat = 1
    let dim = (collectionView.bounds.width - (cellsAcross - 1) * spaceBetweenCells) / cellsAcross
    return CGSize(width: dim, height: dim)
}

这适用于所有尺寸的iPhone和iPad。

答案 1 :(得分:13)

vacawama的答案很棒,但我有2个问题。我希望自动使用我在故事板中定义的间距。

enter image description here

其次,我无法调用此函数,没有人提到如何?要调用collectionView的sizeForItemAt,您需要扩展 UICollectionViewDelegateFlowLayout ,而不是扩展UICollectionViewDelegate。我希望这能节省一些时间。

extension MyViewController: UICollectionViewDelegateFlowLayout, UICollectionViewDataSource {

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let cellsAcross: CGFloat = 3
        var widthRemainingForCellContent = collectionView.bounds.width
        if let flowLayout = collectionViewLayout as? UICollectionViewFlowLayout {
            let borderSize: CGFloat = flowLayout.sectionInset.left + flowLayout.sectionInset.right
            widthRemainingForCellContent -= borderSize + ((cellsAcross - 1) * flowLayout.minimumInteritemSpacing)
        }
        let cellWidth = widthRemainingForCellContent / cellsAcross
        return CGSize(width: cellWidth, height: cellWidth)
    }

}

答案 2 :(得分:7)

我使用CollectionView的委托方法进行设置。这将为您提供2xN设置,但您可以轻松地将其设置为3xN。这是一个截图,您可以在GitHub上参考我的项目...

https://github.com/WadeSellers/GoInstaPro

CollectionView flow layout screenshot

答案 3 :(得分:4)

基于vacawama回答的

Swift 3版本代码

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

        let cellsAcross: CGFloat = 3
        let spaceBetweenCells: CGFloat = 1
        let dim = (collectionView.bounds.width - (cellsAcross - 1) * spaceBetweenCells) / cellsAcross

        return CGSize(width: dim, height: dim)
    }

答案 4 :(得分:0)

这是另一种解决方案,但它仅适用于iPhone6。

我将尝试更新iphone5 / 6plus

特别感谢@vacawama!

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {


        // Compute the dimension of a cell for an NxN layout with space S between
        // cells.  Take the collection view's width, subtract (N-1)*S points for
        // the spaces between the cells, and then divide by N to find the final
        // dimension for the cell's width and height.

        let cellsAcross: CGFloat = 3
        let spaceBetweenCells: CGFloat = 1
        let dim = (collectionView.bounds.width - (cellsAcross - 1) * spaceBetweenCells) / cellsAcross
                print(indexPath.row)

        var width = dim

        //last cell's width
        if(  (indexPath.row + 1) % 3 == 0){
            width = 124

        }else {
            width = 124.5
        }
        print(width)
        return CGSizeMake(width, dim)

    }

    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAtIndex section: Int) -> CGFloat {
        return 1;
    }

    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAtIndex section: Int) -> CGFloat {
        return 1;
    }