关于ios:UICollectionView中的单元格间距

Cell spacing in UICollectionView

如何在UICollectionView的一个部分中设置单元格间距?我知道有一个属性minimumInteritemSpacing,我已经将它设置为5.0,但是间距没有显示为5.0。我已经实现了flowout委托方法。

1
2
3
4
5
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section
{

    return 5.0;
}

但我还是没有得到想要的结果。我认为这是最小间距。没有什么方法可以设置最大间距吗?

simulator sc


支持最初的问题。我试着在UICollectionView上把间距调整到5px,但这不起作用,在UIEdgeInsetsMake(0,0,0,0)上也不起作用。

在UITableView上,我可以通过直接指定一行中的x,y坐标来实现这一点…

enter image description here

以下是我的uiCollectionView代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#pragma mark collection view cell layout / size
- (CGSize)collectionView:(UICollectionView*)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
    return [self getCellSize:indexPath];  // will be w120xh100 or w190x100
    // if the width is higher, only one image will be shown in a line
}

#pragma mark collection view cell paddings
- (UIEdgeInsets)collectionView:(UICollectionView*)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
    return UIEdgeInsetsMake(0, 0, 0, 0); // top, left, bottom, right
}

- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {

    return 5.0;
}

更新:用以下代码解决了我的问题。

enter image description here

视图控制器.m

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#import"ViewController.h"
#import"MagazineCell.h" // created just the default class.

static NSString * const cellID = @"cellID";

@interface ViewController ()

@end

@implementation ViewController

#pragma mark - Collection view
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
    return 1;
}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return 30;
}

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    MagazineCell *mCell = (MagazineCell *)[collectionView dequeueReusableCellWithReuseIdentifier:cellID forIndexPath:indexPath];

    mCell.backgroundColor = [UIColor lightGrayColor];

    return mCell;
}

#pragma mark Collection view layout things
// Layout: Set cell size
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {

    NSLog(@"SETTING SIZE FOR ITEM AT INDEX %d", indexPath.row);
    CGSize mElementSize = CGSizeMake(104, 104);
    return mElementSize;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
    return 2.0;
}

- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {
    return 2.0;
}

// Layout: Set Edges
- (UIEdgeInsets)collectionView:
(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
   // return UIEdgeInsetsMake(0,8,0,8);  // top, left, bottom, right
    return UIEdgeInsetsMake(0,0,0,0);  // top, left, bottom, right
}

@end


我知道这个话题已经过时了,但是如果有人仍然需要正确的答案,你需要的是:

  • 替代标准流布局。
  • 像这样添加实现:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    - (NSArray *) layoutAttributesForElementsInRect:(CGRect)rect {
        NSArray *answer = [super layoutAttributesForElementsInRect:rect];

        for(int i = 1; i < [answer count]; ++i) {
            UICollectionViewLayoutAttributes *currentLayoutAttributes = answer[i];
            UICollectionViewLayoutAttributes *prevLayoutAttributes = answer[i - 1];
            NSInteger maximumSpacing = 4;
            NSInteger origin = CGRectGetMaxX(prevLayoutAttributes.frame);

            if(origin + maximumSpacing + currentLayoutAttributes.frame.size.width < self.collectionViewContentSize.width) {
                CGRect frame = currentLayoutAttributes.frame;
                frame.origin.x = origin + maximumSpacing;
                currentLayoutAttributes.frame = frame;
            }
        }
        return answer;
    }
  • 其中maximumspacking可以设置为您喜欢的任何值。这个技巧保证了细胞间的空间完全等于最大间距!!


    使用水平流布局,我还得到了单元格之间的10点间距。为了消除间距,我需要将minimumLineSpacingminimumInterItemSpacing设置为零。

    1
    2
    3
    4
    5
    UICollectionViewFlowLayout *flow = [[UICollectionViewFlowLayout alloc] init];
    flow.itemSize = CGSizeMake(cellWidth, cellHeight);
    flow.scrollDirection = UICollectionViewScrollDirectionHorizontal;
    flow.minimumInteritemSpacing = 0;
    flow.minimumLineSpacing = 0;

    此外,如果所有单元格的大小相同,则直接在流布局上设置属性而不是使用委托方法更简单、更有效。


    记住,它是最小的行间距,而不是最小的项目间间距或单元格空间。因为CollectionView的滚动方向是水平的。

    如果是垂直的,则需要为单元格之间的水平空间设置单元格空间或项目间空间,为单元格之间的垂直空间设置行距。

    目标C版

    1
    2
    3
    4
    5
    6
    - (CGFloat)collectionView:(UICollectionView *)collectionView
                           layout:(UICollectionViewLayout*)collectionViewLayout
        minimumLineSpacingForSectionAtIndex:(NSInteger)section
        {
            return 20;
        }

    SWIFT版:

    1
    2
    3
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
        return 20
    }


    尝试此代码以确保每个项目之间的间距为5px:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    - (UIEdgeInsets)collectionView:(UICollectionView *) collectionView
                            layout:(UICollectionViewLayout *) collectionViewLayout
            insetForSectionAtIndex:(NSInteger) section {

        return UIEdgeInsetsMake(0, 0, 0, 5); // top, left, bottom, right
    }

    - (CGFloat)collectionView:(UICollectionView *) collectionView
                       layout:(UICollectionViewLayout *) collectionViewLayout
      minimumInteritemSpacingForSectionAtIndex:(NSInteger) section {    
        return 5.0;
    }


    最流行的答案的快速版本。细胞间的空间等于cellSpacing

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    class CustomViewFlowLayout : UICollectionViewFlowLayout {

        let cellSpacing:CGFloat = 4

        override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
            if let attributes = super.layoutAttributesForElementsInRect(rect) {
            for (index, attribute) in attributes.enumerate() {
                    if index == 0 { continue }
                    let prevLayoutAttributes = attributes[index - 1]
                    let origin = CGRectGetMaxX(prevLayoutAttributes.frame)
                    if(origin + cellSpacing + attribute.frame.size.width < self.collectionViewContentSize().width) {
                        attribute.frame.origin.x = origin + cellSpacing
                    }
                }
                return attributes
            }
            return nil
        }
    }


    我发现了一种非常简单的方法,通过使用ib来配置单元格或行之间的间距。

    只需从Storyboard/xib文件中选择uiCollectionView,然后单击下图中指定的"大小检查器"。

    enter image description here

    要以编程方式配置空间,请使用以下属性。

    1)用于设置行间距。

    1
    [self.collectionView setMinimumLineSpacing:5];

    2)用于设置项目/单元格之间的间距。

    1
    [self.collectionView setMinimumInteritemSpacing:5];


    请注意属性名minimumInteritemspacing。这将是项目之间的最小间距,而不是确切的间距。如果将MinimumInteritemspacking设置为某个值,则可以确保间距不会小于该值。但也有可能获得更高的价值。

    实际上,项目之间的间距取决于几个因素:itemsize和sectioninset。集合视图根据这些值动态放置内容。所以你不能保证精确的间距。您应该对sectioninset和minimumInteritemspacing进行一些尝试和错误。


    应答swift 3.0,xcode 8

    1.确保设置集合视图委托

    1
    2
    3
    4
    5
    6
    7
    8
    class DashboardViewController: UIViewController {
        @IBOutlet weak var dashboardCollectionView: UICollectionView!

        override func viewDidLoad() {
            super.viewDidLoad()
            dashboardCollectionView.delegate = self
        }
    }

    2.实现uiCollectionViewDelegateFlowLayout协议,而不是uiCollectionViewDelegate。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    extension DashboardViewController: UICollectionViewDelegateFlowLayout {
        fileprivate var sectionInsets: UIEdgeInsets {
            return .zero
        }

        fileprivate var itemsPerRow: CGFloat {
            return 2
        }

        fileprivate var interitemSpace: CGFloat {
            return 5.0
        }

        func collectionView(_ collectionView: UICollectionView,
                            layout collectionViewLayout: UICollectionViewLayout,
                            sizeForItemAt indexPath: IndexPath) -> CGSize {
            let sectionPadding = sectionInsets.left * (itemsPerRow + 1)
            let interitemPadding = max(0.0, itemsPerRow - 1) * interitemSpace
            let availableWidth = collectionView.bounds.width - sectionPadding - interitemPadding
            let widthPerItem = availableWidth / itemsPerRow

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

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

        func collectionView(_ collectionView: UICollectionView,
                            layout collectionViewLayout: UICollectionViewLayout,
                            minimumLineSpacingForSectionAt section: Int) -> CGFloat {
            return 0.0
        }

        func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
            return interitemSpace
        }
    }


    在头文件中定义UICollectionViewDelegateFlowLayout协议。

    这样实现UICollectionViewDelegateFlowLayout协议的以下方法:

    1
    2
    3
    4
    - (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
    {
        return UIEdgeInsetsMake(5, 5, 5, 5);
    }

    单击此处查看Apple有关UIEdgeInsetMake方法的文档。


    投票的答案(以及快速版本)有一个小问题:右边会有很大的间隔。

    这是因为流布局是定制的,以使单元间距精确,并具有float-left行为。

    我的解决方案是操纵截面插入,使截面居中对齐,但间距正好与指定的一样。

    在下面的屏幕截图中,项目/行间距正好为8磅,而左&右插入部分将大于8磅(使其居中对齐):

    evenly spaced cells

    银行代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    private let minItemSpacing: CGFloat = 8
    private let itemWidth: CGFloat      = 100
    private let headerHeight: CGFloat   = 32

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()

        // Create our custom flow layout that evenly space out the items, and have them in the center
        let layout = UICollectionViewFlowLayout()
        layout.itemSize = CGSize(width: itemWidth, height: itemWidth)
        layout.minimumInteritemSpacing = minItemSpacing
        layout.minimumLineSpacing = minItemSpacing
        layout.headerReferenceSize = CGSize(width: 0, height: headerHeight)

        // Find n, where n is the number of item that can fit into the collection view
        var n: CGFloat = 1
        let containerWidth = collectionView.bounds.width
        while true {
            let nextN = n + 1
            let totalWidth = (nextN*itemWidth) + (nextN-1)*minItemSpacing
            if totalWidth > containerWidth {
                break
            } else {
                n = nextN
            }
        }

        // Calculate the section inset for left and right.
        // Setting this section inset will manipulate the items such that they will all be aligned horizontally center.
        let inset = max(minItemSpacing, floor( (containerWidth - (n*itemWidth) - (n-1)*minItemSpacing) / 2 ) )
        layout.sectionInset = UIEdgeInsets(top: minItemSpacing, left: inset, bottom: minItemSpacing, right: inset)

        collectionView.collectionViewLayout = layout
    }


    间距的简单代码

    1
    2
    let layout = collectionView.collectionViewLayout as! UICollectionViewFlowLayout
    layout.minimumInteritemSpacing = 10 // Some float value

    我使用的是MonoTouch,所以名称和代码会有点不同,但您可以通过确保CollectionView的宽度等于(x*单元格宽度)+(x-1)*最小间距,x=每行单元格的数量来实现这一点。

    只需根据您的最小interitemspacking和单元格宽度执行以下步骤

    1)我们根据单元格大小+当前插入+最小间距计算每行的项目数量。

    1
    2
    float currentTotalWidth = CollectionView.Frame.Width - Layout.SectionInset.Left - Layout.SectionInset.Right (Layout = flowlayout)
    int amountOfCellsPerRow = (currentTotalWidth + MinimumSpacing) / (cell width + MinimumSpacing)

    2)现在您有了所有信息来计算集合视图的预期宽度。

    1
    float totalWidth =(amountOfCellsPerRow * cell width) + (amountOfCellsPerRow-1) * MinimumSpacing

    3)所以当前宽度和预期宽度之间的差异是

    1
    float difference = currentTotalWidth - totalWidth;

    4)现在调整插入(在本例中,我们将其添加到右侧,这样CollectionView的左侧位置保持不变。

    1
    Layout.SectionInset.Right = Layout.SectionInset.Right + difference;

    Vojtech VRBKA的上述解决方案是正确的,但会触发警告:

    warning:UICollectionViewFlowLayout has cached frame mismatch for index path - cached value: This is likely occurring because the flow layout subclass Layout is modify attributes returned by UICollectionViewFlowLayout without copying them

    以下代码应修复此问题:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    class CustomViewFlowLayout : UICollectionViewFlowLayout {

       let cellSpacing:CGFloat = 4

       override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
           let original = super.layoutAttributesForElementsInRect(rect)

           if let original = original {
               let attributes = NSArray.init(array: original, copyItems: true) as! [UICollectionViewLayoutAttributes]

               for (index, attribute) in attributes.enumerate() {
                    if index == 0 { continue }
                    let prevLayoutAttributes = attributes[index - 1]
                    let origin = CGRectGetMaxX(prevLayoutAttributes.frame)
                    if(origin + cellSpacing + attribute.frame.size.width < self.collectionViewContentSize().width) {
                        attribute.frame.origin.x = origin + cellSpacing
                    }
                }
                return attributes
           }
           return nil
       }
    }


    我偶然发现了一个与op类似的问题,不幸的是,由于collectionView的内容无法正确集中,所以接受的答案对我来说不起作用。因此,我提出了一个不同的解决方案,只要求collectionView中的所有项目具有相同的宽度,这似乎是问题中的情况:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #define cellSize 90

    - (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
        float width = collectionView.frame.size.width;
        float spacing = [self collectionView:collectionView layout:collectionViewLayout minimumInteritemSpacingForSectionAtIndex:section];
        int numberOfCells = (width + spacing) / (cellSize + spacing);
        int inset = (width + spacing - numberOfCells * (cellSize + spacing) ) / 2;

        return UIEdgeInsetsMake(0, inset, 0, inset);
    }

    该代码将确保...minimumInteritemSpacing...返回的值是每个collectionViewCell之间的精确间距,并进一步确保所有单元格都集中在collectionView中。


    斯威夫特3版

    只需创建一个uiCollectionViewFlowLayout子类并粘贴此方法。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
            guard let answer = super.layoutAttributesForElements(in: rect) else { return nil }

            for i in 1..<answer.count {
                let currentAttributes = answer[i]
                let previousAttributes = answer[i - 1]

                let maximumSpacing: CGFloat = 8
                let origin = previousAttributes.frame.maxX

                if (origin + maximumSpacing + currentAttributes.frame.size.width < self.collectionViewContentSize.width && currentAttributes.frame.origin.x > previousAttributes.frame.origin.x) {
                    var frame = currentAttributes.frame
                    frame.origin.x = origin + maximumSpacing
                    currentAttributes.frame = frame
                }
            }

            return answer
    }


    如果你想在不触及实际单元格大小的情况下调整间距,这是最适合我的解决方案。#xcode 9 tvos11 ios11 swift

    所以在uicollectionviewdelegateflowlayout中,change实现下一个方法,诀窍是你必须同时使用这两个方法,而文档并没有真正指向我思考的方向。D

    1
    2
    3
    4
    5
    6
    7
    open func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
        return cellSpacing
    }

    public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
        return cellSpacing
    }

    我试过伊阿古849的答案,但效果很好。

    斯威夫特4

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    open override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        guard let answer = super.layoutAttributesForElements(in: rect) else {
            return nil
        }
        let count = answer.count
        for i in 1..<count {
            let currentLayoutAttributes = answer[i]
            let prevLayoutAttributes = answer[i-1]
            let origin = prevLayoutAttributes.frame.maxX
            if (origin + CGFloat(spacing) + currentLayoutAttributes.frame.size.width) < self.collectionViewContentSize.width && currentLayoutAttributes.frame.origin.x > prevLayoutAttributes.frame.origin.x {
                var frame = currentLayoutAttributes.frame
                frame.origin.x = origin + CGFloat(spacing)
                currentLayoutAttributes.frame = frame
            }
        }
        return answer
    }

    这是Github项目的链接。网址:https://github.com/vishalwaka/multitags


    故事板方法

    在故事板中选择CollectionView,转到"大小检查器",并将单元格和行的最小间距设置为5

    ></P>Swift 5程序化</p>
<div class=

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    lazy var collectionView: UICollectionView = {
            let layout = UICollectionViewFlowLayout()
            layout.scrollDirection = .horizontal

            //Provide Width and Height According to your need
            let width = UIScreen.main.bounds.width / 4
            let height = UIScreen.main.bounds.height / 10
            layout.itemSize = CGSize(width: width, height: height)

            //For Adjusting the cells spacing
            layout.minimumInteritemSpacing = 5
            layout.minimumLineSpacing = 5

            return UICollectionView(frame: self.view.frame, collectionViewLayout: layout)
        }()


    以前的版本并不适用于>1的部分。所以我的解决方案就在这里找到了:https://codentrick.com/create-a-tag-flow-layout-with-uicollectionview/。对于懒惰的人:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        let attributesForElementsInRect = super.layoutAttributesForElements(in: rect)
        var newAttributesForElementsInRect = [UICollectionViewLayoutAttributes]()
        // use a value to keep track of left margin
        var leftMargin: CGFloat = 0.0;
        for attributes in attributesForElementsInRect! {
            let refAttributes = attributes
            // assign value if next row
            if (refAttributes.frame.origin.x == self.sectionInset.left) {
                leftMargin = self.sectionInset.left
            } else {
                // set x position of attributes to current margin
                var newLeftAlignedFrame = refAttributes.frame
                newLeftAlignedFrame.origin.x = leftMargin
                refAttributes.frame = newLeftAlignedFrame
            }
            // calculate new value for current margin
            leftMargin += refAttributes.frame.size.width + 10
            newAttributesForElementsInRect.append(refAttributes)
        }

        return newAttributesForElementsInRect
    }

    我对接受的答案有疑问,因此我更新了它,这对我很有用:

    h

    1
    2
    3
    @interface MaxSpacingCollectionViewFlowLayout : UICollectionViewFlowLayout
    @property (nonatomic,assign) CGFloat maxCellSpacing;
    @end

    m

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    @implementation MaxSpacingCollectionViewFlowLayout

    - (NSArray *) layoutAttributesForElementsInRect:(CGRect)rect {
        NSArray *attributes = [super layoutAttributesForElementsInRect:rect];

        if (attributes.count <= 0) return attributes;

        CGFloat firstCellOriginX = ((UICollectionViewLayoutAttributes *)attributes[0]).frame.origin.x;

        for(int i = 1; i < attributes.count; i++) {
            UICollectionViewLayoutAttributes *currentLayoutAttributes = attributes[i];
            if (currentLayoutAttributes.frame.origin.x == firstCellOriginX) { // The first cell of a new row
                continue;
            }

            UICollectionViewLayoutAttributes *prevLayoutAttributes = attributes[i - 1];
            CGFloat prevOriginMaxX = CGRectGetMaxX(prevLayoutAttributes.frame);
            if ((currentLayoutAttributes.frame.origin.x - prevOriginMaxX) > self.maxCellSpacing) {
                CGRect frame = currentLayoutAttributes.frame;
                frame.origin.x = prevOriginMaxX + self.maxCellSpacing;
                currentLayoutAttributes.frame = frame;
            }
        }
        return attributes;
    }

    @end

    我在Swift 3细胞株间距中的解决方案,如instagram:

    enter image description here

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    lazy var collectionView: UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
        cv.backgroundColor = UIColor.rgb(red: 227, green: 227, blue: 227)
        cv.showsVerticalScrollIndicator = false
        layout.scrollDirection = .vertical
        layout.minimumLineSpacing = 1
        layout.minimumInteritemSpacing = 1
        return cv
    }()

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

        switch UIDevice.current.modelName {
        case"iPhone 4":
            return CGSize(width: 106, height: 106)
        case"iPhone 5":
            return CGSize(width: 106, height: 106)
        case"iPhone 6,7":
            return CGSize(width: 124, height: 124)
        case"iPhone Plus":
            return CGSize(width: 137, height: 137)
        default:
            return CGSize(width: frame.width / 3, height: frame.width / 3)
        }
    }

    如何以编程方式检测设备:https://stackoverflow.com/a/26962452/6013170


    我有一个水平的UICollectionView和子类UICollectionViewFlowLayout。集合视图具有较大的单元格,并且一次只显示其中的一行,并且集合视图适合屏幕的宽度。

    我试过了伊阿古849的答案,但后来我发现我甚至不需要他的答案。出于某种原因,设置minimumInterItemSpacing没有任何作用。我的项目/单元格之间的间距完全可以由minimumLineSpacing控制。

    不知道为什么它是这样工作的,但它是工作的。


    试着用这种方法玩:

    1
    2
    3
    4
    5
    6
    7
    8
    - (UIEdgeInsets)collectionView:(UICollectionView *)collectionView
                        layout:(UICollectionViewLayout*)collectionViewLayout
        insetForSectionAtIndex:(NSInteger)section {

        UIEdgeInsets insets = UIEdgeInsetsMake(?, ?, ?, ?);

        return insets;
    }