it-swarm.com.de

Zellenabstand in UICollectionView

Wie lege ich den Zellenabstand in einem Abschnitt von UICollectionView fest? Ich weiß, dass es eine Eigenschaft gibt. minimumInteritemSpacing Ich habe sie auf 5,0 gesetzt, der Abstand wird jedoch nicht mit 5,0 angegeben. Ich habe die Flowout-Delegate-Methode implementiert.

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

    return 5.0;
}

ich erhalte immer noch nicht das gewünschte Ergebnis. Ich denke, es ist der Mindestabstand. Gibt es keine Möglichkeit, wie ich den maximalen Abstand festlegen kann?

simulator sc

183
Vishal Singh

Ich weiß, dass das Thema alt ist, aber falls noch jemand die richtige Antwort braucht, was Sie brauchen:

  1. Überschreiben Sie das Standard-Flow-Layout.
  2. Fügen Sie die Implementierung folgendermaßen hinzu:

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

wobei maximumSpacing auf einen beliebigen Wert eingestellt werden kann. Dieser Trick garantiert, dass der Abstand zwischen den Zellen EXAKT dem maximalen Abstand entspricht !!

137
iago849

Unterstützung der Ausgangsfrage. Ich habe versucht, den Abstand für UICollectionView auf 5px zu setzen, aber das funktioniert nicht, auch mit einer UIEdgeInsetsMake(0,0,0,0) ...

Auf einem UITableView kann ich dies durch direkte Angabe der x, y-Koordinaten in einer Reihe tun ...

enter image description here

Hier ist mein UICollectionView Code:

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

Update: Mein Problem wurde mit folgendem Code behoben.

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

Unter Verwendung eines horizontalen Flusslayouts erhielt ich auch einen Abstand von 10 Punkten zwischen den Zellen. Um den Abstand zu entfernen, musste ich minimumLineSpacing sowie minimumInterItemSpacing auf Null setzen.

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

Wenn alle Zellen dieselbe Größe haben, ist es einfacher und effizienter, die Eigenschaft direkt im Flow-Layout festzulegen, anstatt Delegierungsmethoden zu verwenden.

75
Jason Moore

Denken Sie daran, es ist Mindestzeilenabstand, nicht der Mindestabstand zwischen Elementen oder der Zellenabstand. Weil die Bildlaufrichtung Ihrer collectionView HORIZONTAL ist.

Wenn es vertikal war, müssen Sie den Zellenraum oder den Zwischenraum für den horizontalen Abstand zwischen den Zellen und den Zeilenabstand für den vertikalen Abstand zwischen den Zellen festlegen.

Objective-C-Version

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

Swift version:

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

Probieren Sie diesen Code aus, um sicherzustellen, dass Sie zwischen den einzelnen Elementen einen Abstand von 5 Pixel haben:

- (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 der beliebtesten Antwort. Der Abstand zwischen den Zellen entspricht 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

Ich habe eine sehr einfache Möglichkeit gefunden, den Abstand zwischen Zellen oder Zeilen mithilfe von IB zu konfigurieren.

Wählen Sie einfach UICollectionView aus der Storyboard-/Xib-Datei aus und klicken Sie in Size Inspector (siehe Abbildung unten).

enter image description here

Verwenden Sie zum programmgesteuerten Konfigurieren des Speicherplatzes die folgenden Eigenschaften.

1) Zum Einstellen des Abstands zwischen den Zeilen.

[self.collectionView setMinimumLineSpacing:5];

2) Zum Einstellen des Abstands zwischen Elementen/Zellen.

[self.collectionView setMinimumInteritemSpacing:5];
28
Aamir

Bitte beachten Sie den Eigenschaftsnamen minimumInterItemSpacing. Dies ist der Mindestabstand zwischen den Elementen nicht der exakte Abstand) Abstand. Wenn Sie minimumInterItemSpacing auf einen bestimmten Wert setzen, können Sie sicherstellen, dass der Abstand nicht kleiner als dieser Wert ist. Aber es gibt eine Chance, einen höheren Wert zu bekommen.

Tatsächlich hängt der Abstand zwischen Elementen von mehreren Faktoren ab: itemSize und sectionInset. In der Sammlungsansicht werden die Inhalte basierend auf diesen Werten dynamisch platziert. Sie können also den genauen Abstand nicht sicherstellen. Sie sollten einige Versuche mit sectionInset und minimumInterItemSpacing machen.

19
Anil Varghese

Antwort für Swift 3.0, Xcode 8

1.Stellen Sie sicher, dass Sie den Delegaten für die Sammlungsansicht festgelegt haben

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

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

2.Implement ICollectionViewDelegateFlowLayout Protokoll, nicht 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

Einfacher Code für den Abstand

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

Die gewählte Antwort (und auch die schnelle Version ) haben ein kleines Problem: Rechts wird ein großer Abstand angezeigt.

Dies liegt daran, dass das Flow-Layout so angepasst wird, dass der Zellenabstand exakt ist, wobei das Verhalten nach links schwebt .

Meine Lösung besteht darin, den Abschnittseinsatz so zu manipulieren, dass der Abschnitt mittig ausgerichtet ist, der Abstand jedoch genau dem angegebenen entspricht.

In der Abbildung unten beträgt der Abstand zwischen Element und Zeile genau 8 Punkte, während der Abstand zwischen linkem und rechtem Rand größer als 8 Punkte ist (damit er mittig ausgerichtet wird):

evenly spaced cells

Schneller Code als solcher:

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

Definieren Sie das Protokoll UICollectionViewDelegateFlowLayout in Ihrer Header-Datei.

Implementieren Sie die folgende Methode des UICollectionViewDelegateFlowLayout -Protokolls:

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

Klicken Sie hier um zu sehen Apple Dokumentation der UIEdgeInsetMake Methode.

8
Salman Zaidi

Wenn Sie den Abstand optimieren möchten, ohne die tatsächliche Zellengröße zu berühren, ist dies die Lösung, die für mich am besten funktioniert hat. # xcode 9 # tvOS11 # iOS11 # Swift

In ICollectionViewDelegateFlowLayout implementieren Sie die nächsten Methoden. Der Trick ist, dass Sie beide Methoden verwenden müssen, und die Dokumentation hat mich nicht wirklich dazu gebracht, in diese Richtung zu denken. : D

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

Ich verwende Monotouch, daher sind die Namen und der Code etwas anders. Sie können dies jedoch tun, indem Sie sicherstellen, dass die Breite der Sammlungsansicht gleich (x * Zellenbreite) + (x-1) * Mindestabstand mit x = Betrag ist von Zellen pro Zeile.

Führen Sie einfach die folgenden Schritte aus, die auf Ihrem MinimumInteritemSpacing und der Breite der Zelle basieren

1) Wir berechnen die Anzahl der Elemente pro Zeile basierend auf der Zellengröße + den aktuellen Einfügungen + dem Mindestabstand

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

2) Jetzt haben Sie alle Informationen, um die erwartete Breite für die Sammlungsansicht zu berechnen

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

3) Der Unterschied zwischen der aktuellen und der erwarteten Breite ist also

float difference = currentTotalWidth - totalWidth;

4) Passen Sie nun die Einfügungen an (in diesem Beispiel wird sie rechts hinzugefügt, sodass die linke Position der Sammlungsansicht gleich bleibt

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

Storyboard-Ansatz

Wählen Sie in Ihrem Storyboard "CollectionView" aus, wechseln Sie zum Größeninspektor und legen Sie den Mindestabstand für Zellen und Linien auf 5 fest

Swift 5 programmatisch

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

Die obige Lösung von vojtech-vrbka ist korrekt, löst jedoch eine Warnung aus:

warnung: UICollectionViewFlowLayout hat eine zwischengespeicherte Frame-Nichtübereinstimmung für den zwischengespeicherten Indexpfadwert: Dies ist wahrscheinlich darauf zurückzuführen, dass die von UICollectionViewFlowLayout zurückgegebenen Attribute der Flow-Layout-Unterklasse Layout geändert werden, ohne sie zu kopieren

Der folgende Code sollte es beheben:

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

Ich stieß auf ein ähnliches Problem wie OP. Leider hat die akzeptierte Antwort bei mir nicht funktioniert, da der Inhalt von collectionView nicht richtig zentriert wäre. Aus diesem Grund habe ich eine andere Lösung gefunden, die nur erfordert, dass alle Elemente in collectionView das gleiche Breite haben, was bei der Frage der Fall zu sein scheint:

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

Dieser Code stellt sicher, dass der von ...minimumInteritemSpacing... Zurückgegebene Wert der exakte Abstand zwischen jedem collectionViewCell ist und außerdem gewährleistet, dass die Zellen alle zusammen im collectionView zentriert werden.

1
luk2302

Ich habe die Antwort von iago849 ausprobiert und es hat funktioniert.

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
}

Hier ist der Link für das Github-Projekt. https://github.com/vishalwaka/MultiTags

1
vishalwaka

Ich habe ein horizontales UICollectionView und ein untergeordnetes UICollectionViewFlowLayout. Die Sammlungsansicht enthält große Zellen und zeigt jeweils nur eine Zeile an. Die Sammlungsansicht passt sich an die Breite des Bildschirms an.

Ich habe die Antwort von iago849 ausprobiert und es hat funktioniert, aber dann habe ich herausgefunden, dass ich seine Antwort nicht einmal brauchte. Aus irgendeinem Grund führt das Setzen von minimumInterItemSpacing zu nichts. Der Abstand zwischen meinen Elementen/Zellen kann vollständig von minimumLineSpacing gesteuert werden.

Ich bin nicht sicher, warum es so funktioniert, aber es funktioniert.

1
user3344977

Swift 3 Version

Erstellen Sie einfach eine UICollectionViewFlowLayout-Unterklasse und fügen Sie diese Methode ein.

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

Meine Lösung in Swift 3 Zelllinienabstand wie in 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)
    }
}

So erkennen Sie das Gerät programmgesteuert: https://stackoverflow.com/a/26962452/601317

0
Zhanserik

Frühere Versionen funktionierten nicht wirklich mit Abschnitten> 1. Meine Lösung wurde hier gefunden https://codentrick.com/create-a-tag-flow-layout-with-uicollectionview/ . Für die Faulen:

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
}

Ich habe ein Problem mit der akzeptierten Antwort, daher habe ich sie aktualisiert. Dies funktioniert für mich:

. 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