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)