0

Dies ist ein Follow-up ist Frage von UICollectionViewCell dynamic sizing for 4.4 and 5.5 inchDynamische UICollectionViewCell Breite bezüglich Breite und Seitenverhältnis zu gestalten

Während diese Lösung groß ist, ich möchte eine dynamische Menge Artikel-Zellen (kCellsPerRow) innerhalb des UIViewController erzeugen basierend auf der Breite des Geräts, dem Seitenverhältnis und der Anzahl der insgesamt angezeigten Elemente. Ich kann einfach nicht herausfinden, wie man die richtige Menge von kCellsPerRow berechnet, so dass sie nicht zu groß werden, sobald sie ein Seitenverhältnis-Limit erreicht haben.

Hier ist, was ich bisher:

var kCellsPerRow = ceil(global.TotalAmount)    //Total Amount of Cells 
var windowWidth = layout.collectionView!.frame.width  // Device's Window Width 
var dynamicWidth = windowWidth/CGFloat(kCellsPerRow) // Current Width of Each Cell 
var dynamicHeight = windowWidth/CGFloat(kCellsPerRow) // Current Height of Each Cell 
var limit = (Double(dynamicWidth)/Double(windowWidth))*(9/2) < (2/9) // Constraint/Threshold 

if (limit) { 
    var newkCellsPerRow = CGFloat(kCellsPerRow * (2/9)) // Attempt 
    newkCellsPerRow = 9 // Fixed Size of 9 but what if we can dynamically figure out the perfect number such that its not so tiny! 

    dynamicWidth = layout.collectionView!.frame.width/newkCellsPerRow 
    dynamicHeight = layout.collectionView!.frame.width/newkCellsPerRow 
} 

// Create Cell 
layout.itemSize = CGSize(width: dynamicWidth, height: dynamicHeight) 

Antwort

4

Alles, was Sie angeben müssen, die kleinste Größe ist, sollte eine Zelle sein. Die Zellen werden mindestens so breit (und hoch) wie diese Größe und möglicherweise größer sein.

Ansatz:

Hier ist ein Verfahren, das die entsprechende Zellengröße auf der Basis der Breite seiner Kollektion berechnen wird:

// These variables are set in the Storyboard, but shown here for clarity 
flowLayout.minimumInteritemSpacing = 10 
flowLayout.sectionInset = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10) 

let minimumSize: CGFloat = 90.0 // A cell's width or height won't ever be smaller than this 

func cellWidthForViewWidth(viewWidth: CGFloat) -> CGFloat { 
    // Determine the largest number of cells that could possibly fit in a row, based on the cell's minimum size 
    var numberOfCellsPerRow = Int(viewWidth/minimumSize) 

    // Adjust for interitem spacing and section insets 
    let availableWidth = viewWidth - flowLayout.sectionInset.left - flowLayout.sectionInset.right - flowLayout.minimumInteritemSpacing * CGFloat(numberOfCellsPerRow - 1) 
    numberOfCellsPerRow = Int(availableWidth/minimumSize) 

    return availableWidth/CGFloat(numberOfCellsPerRow) // Make this an integral width if desired 
} 

ein nicht 1 Behandlung: 1 Seitenverhältnis:

Wenn Ihr Seitenverhältnis zufällig von 1: 1 abweicht, würden Sie einfach die dynamische Höhe bestimmen, indem Sie die berechnete Breite durch das Seitenverhältnis ra dividieren tio.

let aspectRatio: CGFloat = 3.0/2.0 
let cellWidth = cellWidthForViewWidth(CGRectGetWidth(collectionView.frame)) 
let cellHeight = cellWidth/aspectRatio 

die Objektgröße einstellen:

Da Ihr Seitenverhältnis 1: 1, wir brauchen nur die Breite für eine Zelle zu berechnen, verwenden Sie dann den Wert für Breite und Höhe.

Set die tatsächliche Objektgröße auf der berechneten dynamischen Größe basiert:

let actualCellSize = cellWidthForViewWidth(CGRectGetWidth(collectionView.frame)) 
flowLayout.itemSize = CGSize(width: actualCellSize, height: actualCellSize) 

Beispielergebnisse:

Dies gibt Ihnen eine Vorstellung, welche Größe eine Zelle, basierend auf verschiedenen Containerbreiten sein würde :

print(cellWidthForViewWidth(320.0)) // 93, 3 cells per row 
print(cellWidthForViewWidth(400.0)) // 116, 3 cells per row 
print(cellWidthForViewWidth(640.0)) // 93, 6 cells per row 
print(cellWidthForViewWidth(800.0)) // 101, 7 cells per row 
print(cellWidthForViewWidth(1024.0)) // 90, 10 cells per row