uicollectionviewflowlayoutautomaticsize uicollectionviewdelegateflowlayout systemlayoutsizefitting collection automatic swift dynamic uicollectionview uicollectionviewcell uicollectionviewlayout

swift - uicollectionviewdelegateflowlayout - Ancho de UICollectionViewCell dinámico con respecto al ancho del marco y la relación de aspecto



uicollectionview dynamic cell size swift (1)

Todo lo que necesita especificar es el tamaño más pequeño que debe tener una celda. Las celdas serán al menos tan anchas (y altas) como ese tamaño, y posiblemente más grandes.

Enfoque:

Aquí hay un método que calculará el tamaño de celda apropiado en función del ancho de su collectionView:

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

Manejo de una relación de aspecto no 1: 1:

Si su relación de aspecto era diferente de 1: 1, simplemente determinaría la altura dinámica dividiendo el ancho calculado por la relación de aspecto.

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

Configurando el tamaño del artículo:

Como su relación de aspecto es 1: 1, solo necesitamos calcular el ancho de una celda, luego usar ese valor para ancho y alto.

Establezca el tamaño real del artículo en función del tamaño dinámico calculado:

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

Resultados de muestra:

Esto le dará una idea del tamaño de una celda, según el ancho de varios contenedores:

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

Esta es una pregunta de seguimiento del tamaño dinámico UICollectionViewCell para 4.4 y 5.5 pulgadas

Si bien esa solución es excelente, me gustaría generar una cantidad dinámica de celdas de elementos (kCellsPerRow) dentro del UIVIewController en función del ancho del dispositivo, la relación de aspecto y la cantidad total de elementos que tengo que mostrar. Simplemente no puedo entender cómo calcular la cantidad correcta de kCellsPerRow para que no se modifiquen demasiado una vez que alcanzan un límite de relación de aspecto.

Esto es lo que tengo hasta ahora:

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)