swift3 uicollectionview uicollectionviewcell uicollectionviewlayout

swift3 - UICollectionView Layout como SnapChat?



uicollectionviewcell uicollectionviewlayout (2)

Basado en una respuesta precedente adaptada a su problema:

-(id)initWithSize:(CGSize)size { self = [super init]; if (self) { _unitSize = CGSizeMake(size.width/2,80); _cellLayouts = [[NSMutableDictionary alloc] init]; } return self; } -(void)prepareLayout { for (NSInteger aSection = 0; aSection < [[self collectionView] numberOfSections]; aSection++) { //Create Cells Frames for (NSInteger aRow = 0; aRow < [[self collectionView] numberOfItemsInSection:aSection]; aRow++) { NSIndexPath *indexPath = [NSIndexPath indexPathForItem:aRow inSection:aSection]; UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath]; NSUInteger i = aRow%3; NSUInteger j = aRow/3; CGFloat offsetY = _unitSize.height*2*j; CGPoint xPoint; CGFloat height = 0; BOOL invert = NO; if (aRow%6 >= 3) //We need to invert Big cell and small cells => xPoint.x { invert = YES; } switch (i) { case 0: xPoint = CGPointMake((invert?_unitSize.width:0), offsetY); height = _unitSize.height; break; case 1: xPoint = CGPointMake((invert?_unitSize.width:0), offsetY+_unitSize.height); height = _unitSize.height; break; case 2: xPoint = CGPointMake((invert?0:_unitSize.width), offsetY); height = _unitSize.height*2; break; default: break; } CGRect frame = CGRectMake(xPoint.x, xPoint.y, _unitSize.width, height); [attributes setFrame:frame]; [_cellLayouts setObject:attributes forKey:indexPath]; } } }

Configuré la altura de unitSize en 80, pero puede usar el tamaño de la pantalla si es necesario, como _unitSize = CGSizeMake(size.width/2,size.height/4.); .

Que rinden:

Nota al margen: Depende de usted adaptar la lógica o hacer cambios, el cálculo de los marcos de las celdas puede no ser el "código de mejor aspecto".

¿Cómo creamos un UICollectionViewLayout como las historias de SnapChat?

Alguna idea por favor?

Me gustaría tener una solución sin biblioteca externa.


UICollectionViewLayout como las historias de SnapChat Me gusta


Código Swift 3.2

import Foundation import UIKit class StoryTwoColumnsLayout : UICollectionViewLayout { fileprivate var cache = [IndexPath: UICollectionViewLayoutAttributes]() fileprivate var cellPadding: CGFloat = 4 fileprivate var contentHeight: CGFloat = 0 var oldBound: CGRect! let numberOfColumns:Int = 2 var cellHeight:CGFloat = 255 fileprivate var contentWidth: CGFloat { guard let collectionView = collectionView else { return 0 } let insets = collectionView.contentInset return collectionView.bounds.width - (insets.left + insets.right) } override var collectionViewContentSize: CGSize { return CGSize(width: contentWidth, height: contentHeight) } override func prepare() { super.prepare() contentHeight = 0 cache.removeAll(keepingCapacity: true) guard cache.isEmpty == true, let collectionView = collectionView else { return } if collectionView.numberOfSections == 0 { return } let cellWidth = contentWidth / CGFloat(numberOfColumns) cellHeight = cellWidth / 720 * 1220 var xOffset = [CGFloat]() for column in 0 ..< numberOfColumns { xOffset.append(CGFloat(column) * cellWidth) } var column = 0 var yOffset = [CGFloat](repeating: 0, count: numberOfColumns) for item in 0 ..< collectionView.numberOfItems(inSection: 0) { let indexPath = IndexPath(item: item, section: 0) var newheight = cellHeight if column == 0 { newheight = ((yOffset[column + 1] - yOffset[column]) > cellHeight * 0.3) ? cellHeight : (cellHeight * 0.90) } let frame = CGRect(x: xOffset[column], y: yOffset[column], width: cellWidth, height: newheight) let insetFrame = frame.insetBy(dx: cellPadding, dy: cellPadding) let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath) attributes.frame = insetFrame cache[indexPath] = (attributes) contentHeight = max(contentHeight, frame.maxY) yOffset[column] = yOffset[column] + newheight if column >= (numberOfColumns - 1) { column = 0 } else { column = column + 1 } } } override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? { var visibleLayoutAttributes = [UICollectionViewLayoutAttributes]() // Loop through the cache and look for items in the rect visibleLayoutAttributes = cache.values.filter({ (attributes) -> Bool in return attributes.frame.intersects(rect) }) print(visibleLayoutAttributes) return visibleLayoutAttributes } override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? { // print(cache[indexPath.item]) return cache[indexPath] } }