Wie stelle ich den Zellenabstand und das Größenverhältnis von UICollectionView - UICollectionViewFlowLayout ein?


137

Ich versuche , hinzufügen UICollectionViewzu ViewController, und ich brauche 3 - Zellen haben ‚pro Zeile‘ ohne Leerzeichen zwischen den Zellen (wie ein Gitter aussehen soll). Die Zellenbreite sollte ein Drittel der Bildschirmgröße betragen, daher dachte ich, dass die layout.itemBreite gleich sein sollte. Aber dann verstehe ich das:

layout.itemSize width = screenSize.width / 3

Wenn ich diese Größe reduziere ( z. B. um 7 oder 8 Pixel ), ist es besser, aber die dritte Zelle in der Reihe ist nicht vollständig sichtbar, und ich habe immer noch diese Leerstelle (oben und unten sowie links und rechts).

Geben Sie hier die Bildbeschreibung ein

class ViewController: UIViewController, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource {
    var collectionView: UICollectionView?
    var screenSize: CGRect!
    var screenWidth: CGFloat!
    var screenHeight: CGFloat!

    override func viewDidLoad() {
        super.viewDidLoad()

        screenSize = UIScreen.mainScreen().bounds
        screenWidth = screenSize.width
        screenHeight = screenSize.height

        // Do any additional setup after loading the view, typically from a nib
        let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
        layout.sectionInset = UIEdgeInsets(top: 20, left: 0, bottom: 10, right: 0)
        layout.itemSize = CGSize(width: screenWidth / 3, height: screenWidth / 3)
        collectionView = UICollectionView(frame: self.view.frame, collectionViewLayout: layout)
        collectionView!.dataSource = self
        collectionView!.delegate = self
        collectionView!.registerClass(CollectionViewCell.self, forCellWithReuseIdentifier: "CollectionViewCell")
        collectionView!.backgroundColor = UIColor.greenColor()
        self.view.addSubview(collectionView!)
    }

    func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
        return 1
    }

    func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 20
    }

    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier("CollectionViewCell", forIndexPath: indexPath) as CollectionViewCell
        cell.backgroundColor = UIColor.whiteColor()
        cell.layer.borderColor = UIColor.blackColor().CGColor
        cell.layer.borderWidth = 0.5
        cell.frame.size.width = screenWidth / 3
        cell.frame.size.height = screenWidth / 3

        cell.textLabel?.text = "\(indexPath.section):\(indexPath.row)"
        return cell
    }
}

Hier ist Ihre Lösung. Vielen Dank.
Janu Kansagra

Antworten:


299

Fügen Sie diese 2 Zeilen hinzu

layout.minimumInteritemSpacing = 0
layout.minimumLineSpacing = 0

Also hast du:

   // Do any additional setup after loading the view, typically from a nib.
        let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
        layout.sectionInset = UIEdgeInsets(top: 20, left: 0, bottom: 10, right: 0)
        layout.itemSize = CGSize(width: screenWidth/3, height: screenWidth/3)
        layout.minimumInteritemSpacing = 0
        layout.minimumLineSpacing = 0
        collectionView!.collectionViewLayout = layout

Dadurch werden alle Leerzeichen entfernt und Sie erhalten ein Rasterlayout:

Geben Sie hier die Bildbeschreibung ein

Wenn die erste Spalte eine Breite haben soll, die der Bildschirmbreite entspricht, fügen Sie die folgende Funktion hinzu:

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
    if indexPath.row == 0
    {
        return CGSize(width: screenWidth, height: screenWidth/3)
    }
    return CGSize(width: screenWidth/3, height: screenWidth/3);

}

Das Rasterlayout sieht nun folgendermaßen aus (ich habe der ersten Zelle auch einen blauen Hintergrund hinzugefügt): Geben Sie hier die Bildbeschreibung ein


Vielen Dank, ich hatte etwas viel Komplizierteres erwartet und zu viel Zeit damit verbracht. Nochmals vielen Dank.
Marko

Und nur noch eins: Gibt es eine Möglichkeit, layout.itemSize nur für die erste Zelle zu ändern ? (Ich weiß, dass ich cell.frame.size ändern muss, wenn indexPath.row 0 ist, weiß aber nicht, wie ich die Layoutgröße nur für ein Element ändern soll . ) Die erste Elementbreite sollte gleich screenWidth sein .
Marko

1
Hallo, ich habe das gleiche Problem, aber ich möchte den ähnlichen Funktionstitel in Ziel C kennen.
Nada Gamal

1
Ok, es funktioniert jetzt gut. Vielen Dank :) Ziel C-Funktion: - (CGSize) collectionView: (UICollectionView ) collectionView-Layout: (UICollectionViewLayout ) collectionViewLayout sizeForItemAtIndexPath: (NSIndexPath *) indexPath {return CGSizeMake (screenWidth / 3, ); }
Nada Gamal

4
danke für die tolle antwort @greentor. schickte ein Kopfgeld. Vergessen Sie nicht die collectionView! .CollectionViewLayout = Layout , Leser
Fattie

46

Für Swift 3 und XCode 8 funktionierte dies. Führen Sie die folgenden Schritte aus, um dies zu erreichen: -

{
    let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
    let width = UIScreen.main.bounds.width
    layout.sectionInset = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5)
    layout.itemSize = CGSize(width: width / 2, height: width / 2)
    layout.minimumInteritemSpacing = 0
    layout.minimumLineSpacing = 0
    collectionView!.collectionViewLayout = layout
}

Fügen Sie diesen Code in die Funktion viewDidLoad () ein.


32

In bestimmten Situationen wirkt sich das Festlegen von UICollectionViewFlowLayoutin viewDidLoadoder ViewWillAppearmöglicherweise nicht auf die collectionView aus.

Die Einstellung UICollectionViewFlowLayoutin viewDidAppearkann bewirken , dass die Veränderungen der Zellen Größen im laufenden Betrieb sehen.

Eine andere Lösung in Swift 3:

extension YourViewController : UICollectionViewDelegateFlowLayout{

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
        return UIEdgeInsets(top: 20, left: 0, bottom: 10, right: 0)
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let collectionViewWidth = collectionView.bounds.width
        return CGSize(width: collectionViewWidth/3, height: collectionViewWidth/3)
    }

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

Gute Antwort! Dies ist definitiv der Apple-Weg, dies zu tun. Jetzt wissen Sie nicht, wie Sie aktualisieren sollen, wenn das Gerät die Ausrichtung ändert, oder?
jlstr

17

Wenn Sie nach Swift 3 suchen, befolgen Sie die folgenden Schritte, um dies zu erreichen:

func viewDidLoad() {

    //Define Layout here
    let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()

    //Get device width
    let width = UIScreen.main.bounds.width

    //set section inset as per your requirement.
    layout.sectionInset = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5)

    //set cell item size here 
    layout.itemSize = CGSize(width: width / 2, height: width / 2)

    //set Minimum spacing between 2 items
    layout.minimumInteritemSpacing = 0

    //set minimum vertical line spacing here between two lines in collectionview
    layout.minimumLineSpacing = 0

    //apply defined layout to collectionview
    collectionView!.collectionViewLayout = layout

}

Dies wird auf Xcode 8.0 mit Swift 3 überprüft.


8
let layout = myCollectionView.collectionViewLayout as? UICollectionViewFlowLayout
layout?.minimumLineSpacing = 8

4

Swift 4

let collectionViewLayout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout
collectionViewLayout?.sectionInset = UIEdgeInsetsMake(0, 20, 0, 40) 
collectionViewLayout?.invalidateLayout()

1

Für Swift 3 und XCode 8 funktionierte dies. Führen Sie die folgenden Schritte aus, um dies zu erreichen: -

viewDidLoad()
    {
        let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
        var width = UIScreen.main.bounds.width
        layout.sectionInset = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5)
    width = width - 10
    layout.itemSize = CGSize(width: width / 2, height: width / 2)
        layout.minimumInteritemSpacing = 0
        layout.minimumLineSpacing = 0
        collectionView!.collectionViewLayout = layout
    }

3
Wie man die Tatsache berücksichtigt, wenn Sie mehrere Abschnitte haben
Nikhil Pandey

es ist nur für 1 Spalte (Abschnitt)
user924

0

Für Swift 3+ und Xcode 9+ Versuchen Sie dies

extension ViewController: UICollectionViewDelegateFlowLayout {

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

    let collectionWidth = collectionView.bounds.width
    return CGSize(width: collectionWidth/3, height: collectionWidth/3)

}

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

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

}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.