当前位置: > > > Swift - 设置网格UICollectionView的单元格间距

Swift - 设置网格UICollectionView的单元格间距

(本文代码已升级至Swift3)

要设置单元格cell的间距(水平间距,垂直间距)可进行如下设置:

方法1:在storyboard中设置
选择Collection View后在面板里设置Min Spacing相关属性(这里也可以设置单元格大小)


方法2:在代码里设置
import UIKit

class ViewController: UICollectionViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
       
        let flow = self.collectionViewLayout as! UICollectionViewFlowLayout
        //水平间隔
        flow.minimumInteritemSpacing = 5.0
        //垂直行间距
        flow.minimumLineSpacing = 5.0   
    }
}

注意:这个设置的是允许的最小间距,程序可能会自动调整的
如下图,单元格尺寸固定为100*100。同时将水平间距、垂直间距都设为2。虽然垂直间距没问题,但由于水平间距如果是2的话,一行摆3个单元格填充不满一行,一行摆4个单元格又不够。
那么程序就会自动调大单元格的水平间距,让一行里面均匀地分布3个单元格。
如果想要使间距不发生变化,可以有如下两种方法(或是这两种方法的结合):

方法1:让单元格宽度动态变化
比如下图,每行摆放3个单元格,每个单元格的宽度是:(视图宽度 - 2个间距)/ 3。这样无论屏幕尺寸如何变化,水平间距都是固定的。
override func viewDidLoad() {
    super.viewDidLoad()
    
    self.collectionView?.backgroundColor = UIColor.white
    let layout = self.collectionViewLayout as! UICollectionViewFlowLayout
    //间隔
    let spacing:CGFloat = 2
    //水平间隔
    layout.minimumInteritemSpacing = spacing
    //垂直行间距
    layout.minimumLineSpacing = spacing
    
    //列数
    let columnsNum = 3
    //整个view的宽度
    let collectionViewWidth = self.collectionView!.bounds.width
    //计算单元格的宽度
    let itemWidth = (collectionViewWidth - spacing * CGFloat(columnsNum-1))
        / CGFloat(columnsNum)
    //设置单元格宽度和高度
    layout.itemSize = CGSize(width:itemWidth, height:itemWidth)
}

方法2:单元格宽度固定,两侧设置内边距
如下图,单元格和水平间距是固定的,但在两侧设置内边距,每个边距宽度是:(视图宽度 -2个间距 -3个单元格宽度)/ 2
(当然也可以只在一侧设置被边距,比如右侧留白)
override func viewDidLoad() {
    super.viewDidLoad()
    
    self.collectionView?.backgroundColor = UIColor.white
    let layout = self.collectionViewLayout as! UICollectionViewFlowLayout
    //间隔
    let spacing:CGFloat = 2
    //水平间隔
    layout.minimumInteritemSpacing = spacing
    //垂直行间距
    layout.minimumLineSpacing = spacing
    
    //列数
    let columnsNum = 3
    //整个view的宽度
    let collectionViewWidth = self.collectionView!.bounds.width
    let leftGap = (collectionViewWidth - spacing * CGFloat(columnsNum-1)
        - CGFloat(columnsNum) * layout.itemSize.width) / 2
    print(leftGap)
    layout.sectionInset = UIEdgeInsets(top: 0, left: leftGap, bottom: 0, right: leftGap)
}

评论5
  • 5楼
    2018-01-01 13:44
    沸腾

    你好,请问swift如何使用代码约束一个东西?例如用代码设置边距,用代码进行垂直居中或水平居中。

    站长回复

    1,可以使用自带的Constraint约束进行布局,具体可以参考我的这篇文章:Swift - 使用Auto Layout和Size Classes实现页面自适应弹性布局

    2,也可以使用第三方的布局,使用更简单些。具体可以参考我的这篇文章:Swift - 自动布局库SnapKit的使用详解

  • 4楼
    2017-11-02 16:09
    天天

    航哥您好,CollectionView. 不同分组的背景颜色设置不同,要怎么处理呀

    站长回复

    通过自定义布局可以实现,我这两天会写篇相关的文章,你可以关注下。

  • 3楼
    2017-06-11 01:05
    土豆

    航哥您好,想请教您一个问题,用Collection View单元格加载相册图片,为什么在iPhone5,6,7,上可以正常显示3个单元格,间距是2,但是到了6plus和7plus上就变成了两个单元格呢,并且中间有特别大的间距。这是为什么呢,代码我是从网上下载的,并没有很复杂,可是就是找不出了是哪里出了问题。请问这个可能是什么原因导致的呢。

    站长回复

    不太确定你那边是什么情况,我测试了文章的代码。间距固定2,然后宽度动态计算是可以保证不同设备下都是3个单元格的。

  • 2楼
    2016-07-03 20:28
    小虫

    航哥,我就是想用collectionview实现九宫格,我使用纯代码,使用了你的方法1,间隔spacing设置为1。在真机iPhone5S上运行,看起来间隔都是相等的。但是换成真机iPhone6,左边一个间隔和右边一个间隔明显看起来不一样(左边的粗一点,右边细一点)。航哥,请问这个问题怎么解决哇

    站长回复

    iphone5s屏幕横向宽度是320,间隔为1,那么每个单元格宽度是 (320-2)/3 = 106刚好整除。

    而6的屏幕横向宽度是375,如果间隔还是1的话,每个单元格宽度就是 (375-2)/3 = 124.33333 。除不断就会出现你说的这个问题。
    解决办法:
    (1)设置的时候判断下,不要固定使用间隔为1。比如5你用1,6间隔可以用1.5。
    (2)如果非要在所有得设备下的间隔都一样,只能用方法2了。还是要根据尺寸判断下,在两侧留一或二个像素,保证中间的单元格尺寸能除的断。

  • 1楼
    2015-12-25 12:52
    腾飞

    这个设置是最小间距,但是实际显示出来不是这个效果啊,求问怎么让最小间距就是cell之间的间距啊

    站长回复

    因为你设置的(单元格宽度+最小间距)不能刚好撑满一行。可以参考我文章新补充的内容。