web-dev-qa-db-fra.com

Espacement des cellules dans UICollectionView

Comment définir l'espacement des cellules dans une section de UICollectionView? Je sais qu'il existe une propriété minimumInteritemSpacing je l'ai définie sur 5.0, mais l'espacement n'apparaît pas 5.0. J'ai implémenté la méthode déléguée flowout.

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

    return 5.0;
}

je n'obtiens toujours pas le résultat souhaité. Je pense que c'est l'espacement minimum. N'y a-t-il pas moyen de définir l'espacement maximal?

simulator sc

183
Vishal Singh

Je sais que le sujet est ancien, mais dans le cas où quelqu'un aurait encore besoin d'une réponse correcte, voici ce dont vous avez besoin:

  1. Ignorer la disposition de flux standard.
  2. Ajouter une implémentation comme ça:

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

où maximumSpacing peut être défini sur la valeur de votre choix. Cette astuce garantit que l'espace entre les cellules sera EXACTEMENT égal à maximumSpacing !!

137
iago849

Soutenir la question initiale. J'ai essayé d'obtenir l'espacement à 5px sur le UICollectionView mais cela ne fonctionne pas, aussi bien avec un UIEdgeInsetsMake(0,0,0,0)...

Sur un UITableView, je peux le faire en spécifiant directement les coordonnées x, y dans une ligne ...

enter image description here

Voici mon code UICollectionView:

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

Mise à jour: résolu mon problème, avec le code suivant.

enter image description here

ViewController.m

#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
184
jerik

En utilisant une disposition d'écoulement horizontal, j'obtenais également un espacement de 10 points entre les cellules. Pour supprimer l'espacement, je devais régler minimumLineSpacing ainsi que minimumInterItemSpacing à zéro.

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

De plus, si toutes vos cellules ont la même taille, il est plus simple et plus efficace de définir directement la propriété sur la présentation du flux plutôt que d'utiliser des méthodes de délégation.

75
Jason Moore

Rappelez-vous que c'est espace minimum, pas l'espacement minimum entre les éléments ou l'espace entre les cellules. Parce que la direction de défilement de votre collectionView est HORIZONTAL.

S'il était vertical, vous devez définir un espace cellule ou un espace entre éléments pour un espace horizontal entre cellules et un interligne pour un espace vertical entre deux cellules.

version Objective-C

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

version Swift:

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

Essayez ce code pour vous assurer que vous avez un espacement de 5px entre chaque élément:

- (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;
}
34
LASoft

Swift version de la réponse la plus populaire. L'espace entre les cellules sera égal à cellSpacing.

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
    }
}
30
Vojtech Vrbka

J'ai trouvé un moyen très simple de configurer l'espacement entre les cellules ou les lignes à l'aide de IB.

Il suffit de sélectionner UICollectionView dans le fichier Storyboard/Xib et de cliquer sur Inspecteur de taille comme spécifié dans l'image ci-dessous.

enter image description here

Pour configurer l'espace par programme, utilisez les propriétés suivantes.

1) Pour définir l’espace entre les rangées.

[self.collectionView setMinimumLineSpacing:5];

2) Pour définir un espace entre les éléments/cellules.

[self.collectionView setMinimumInteritemSpacing:5];
28
Aamir

Veuillez noter le nom de la propriété minimumInterItemSpacing . Ce sera le espacement minimum entre les éléments pas l'espacement exact . Si vous définissez minimumInterItemSpacing sur une valeur, vous pouvez vous assurer que l'espacement ne sera pas inférieur à celui-ci. Mais il y a une chance d'obtenir une valeur plus élevée.

En fait, l'espacement entre les éléments dépend de plusieurs facteurs itemSize et sectionInset . La vue Collection place dynamiquement le contenu en fonction de ces valeurs. Donc, vous ne pouvez pas assurer l'espacement exact. Vous devez faire quelques essais et erreurs avec sectionInset et minimumInterItemSpacing .

19
Anil Varghese

Réponse pour Swift 3.0, Xcode 8

1.Assurez-vous de définir le délégué de la vue de collection

class DashboardViewController: UIViewController {
    @IBOutlet weak var dashboardCollectionView: UICollectionView!

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

2.Implement ICollectionViewDelegateFlowLayout protocole, pas UICollectionViewDelegate.

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
    }
}
16
Vadim Bulavin

Code simple pour l'espacement

let layout = collectionView.collectionViewLayout as! UICollectionViewFlowLayout
layout.minimumInteritemSpacing = 10 // Some float value
9
AMayes

Le réponse votée (ainsi que le version Swift ) a un petit problème: il y aura un grand espacement à droite.

En effet, la présentation du flux est personnalisée pour rendre l'espacement des cellules exact, avec un comportement float left .

Ma solution consiste à manipuler l’insert de section, de sorte que la section soit alignée au centre, mais que l’espacement soit exactement tel que spécifié.

Dans la capture d'écran ci-dessous, l'interligne est exactement 8 pt, tandis que les sections insérées à gauche et à droite seront plus grandes que 8 pt (pour l'aligner au centre):

evenly spaced cells

Code Swift en tant que tel:

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

Définissez le protocole UICollectionViewDelegateFlowLayout dans votre fichier d’en-tête.

Implémentez la méthode suivante du protocole UICollectionViewDelegateFlowLayout comme ceci:

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

Cliquez ici pour voir Apple Documentation de la méthode UIEdgeInsetMake.

8
Salman Zaidi

Si vous voulez modifier l’espacement sans toucher à la taille réelle de la cellule, c’est la solution qui vous convient le mieux. # xcode 9 # tvOS11 # iOS11 # Swift

Donc, dans ICollectionViewDelegateFlowLayout, le changement implémente les méthodes suivantes, l’astuce consiste à les utiliser toutes les deux, et la documentation ne m’obligeait pas vraiment à penser dans cette direction. :RÉ

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

J'utilise monotouch, donc les noms et le code seront un peu différents, mais vous pouvez le faire en vous assurant que la largeur de la collection view est égale à (x * largeur de la cellule) + (x-1) * MinimumSpacing avec x = montant de cellules par ligne.

Il suffit de suivre les étapes suivantes en fonction de votre MinimumInteritemSpacing et de la largeur de la cellule

1) Nous calculons le nombre d'éléments par ligne en fonction de la taille de la cellule + des incrustations actuelles + de l'espacement minimum

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

2) Vous avez maintenant toutes les informations pour calculer la largeur attendue pour la vue de collection

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

3) La différence entre la largeur actuelle et la largeur attendue est donc égale à

float difference = currentTotalWidth - totalWidth;

4) Ajustez maintenant les incrustations (dans cet exemple, nous l’ajoutons à droite, pour que la position gauche de la collectionview reste la même

Layout.SectionInset.Right = Layout.SectionInset.Right + difference;
2
Matt

Approche Storyboard

Sélectionnez CollectionView dans votre scénario, accédez à Inspecteur de taille et définissez un espacement minimum de 5 pour les cellules et les lignes.

Swift 5 par programme

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)
    }()
2
Shubham Mishra

Le solution ci-dessus par vojtech-vrbka est correct mais il déclenche un avertissement:

avertissement: UICollectionViewFlowLayout a mis en cache une incompatibilité de cadre pour le chemin d'index - valeur mise en cache: cela est probablement dû au fait que la sous-classe de présentation du flux Layout correspond aux attributs de modification renvoyés par UICollectionViewFlowLayout sans les copier.

Le code suivant devrait résoudre ce problème:

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

Je suis tombé sur un problème similaire à OP. Malheureusement, la réponse acceptée ne fonctionnait pas pour moi car le contenu de la collectionView ne serait pas correctement centré. Par conséquent, j’ai proposé une solution différente qui exige seulement que tous les éléments de la collectionView aient la même largeur , ce qui semble être le cas dans la question:

#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);
}

Ce code garantira que la valeur renvoyée par ...minimumInteritemSpacing... sera l'espacement exact entre chaque collectionViewCell et garantira en outre que toutes les cellules seront centrées dans la collectionView

1
luk2302

J'ai essayé la réponse de iago849 et cela a fonctionné.

Swift 4

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
}

Voici le lien pour le projet github. https://github.com/vishalwaka/MultiTags

1
vishalwaka

J'ai un UICollectionView horizontal et une sous-classe UICollectionViewFlowLayout. La vue Collection contient de grandes cellules et n'en affiche qu'une ligne à la fois. La vue Collection correspond à la largeur de l'écran.

J'ai essayé la réponse de iago849 et cela a fonctionné, mais j'ai ensuite découvert que je n'avais même pas besoin de sa réponse. Pour une raison quelconque, la définition de minimumInterItemSpacing ne fait rien. L'espacement entre mes éléments/cellules peut être entièrement contrôlé par minimumLineSpacing.

Vous ne savez pas pourquoi cela fonctionne de cette façon, mais cela fonctionne.

1
user3344977

Version Swift

Créez simplement une sous-classe UICollectionViewFlowLayout et collez cette méthode.

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

Ma solution dans Swift 3 l'espacement des lignes de cellules, comme dans Instagram:

enter image description here

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

Comment détecter le périphérique par programmation: https://stackoverflow.com/a/26962452/601317

0
Zhanserik

Les versions précédentes ne fonctionnaient pas vraiment avec les sections> 1. Donc ma solution a été trouvée ici https://codentrick.com/create-a-tag-flow-layout-with-uicollectionview/ . Pour les paresseux:

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

J'ai un problème avec la réponse acceptée, alors je l'ai mise à jour, cela fonctionne pour moi:

. h

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

. m

@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
0
Yun CHEN