As per the header, I\'m using UICollectionView to display images. I need to display 3 cells per row, something like how Instagram does it.
Because there are many screen
Replace this line
let width = (bounds.size.width - leftAndRightPaddings) / numberOfItemsPerRow
with
let width = (bounds.size.width - leftAndRightPaddings*4) / numberOfItemsPerRow
As you are not considering spacing between two items & Right insets spacing therefore it is not adjusting in the screen.
private let leftAndRightPaddings: CGFloat = 15.0
private let numberOfItemsPerRow: CGFloat = 3.0
let bounds = UIScreen.mainScreen().bounds
let width = (bounds.size.width - leftAndRightPaddings*(numberOfItemsPerRow+1)) / numberOfItemsPerRow
let layout = userDetailCollection.collectionViewLayout as! UICollectionViewFlowLayout
layout.itemSize = CGSizeMake(width, width)
Try this code
overriding UICollectionViewLayout
will let you much more flexibility in creating collectionViews. here is a snippet for YourOwnCollectionViewLayout : UICollectionViewLayout
:
- (NSInteger)itemWidth {
return (self.collectionView.bounds.size.width - (HORIZONTAL_PAD * (NUMBER_OF_ITEMS_PER_ROW+1))) / NUMBER_OF_ITEMS_PER_ROW; // pad from each side + pad in the middle
}
- (NSInteger)itemHeight {
return self.itemWidth; // or something else
}
- (NSString *)keyForIndexPath:(NSIndexPath *)indexPath {
NSString *retVal = [NSString stringWithFormat:@"%ld-%ld", (long)indexPath.section, (long)indexPath.row];
return retVal;
}
- (CGRect)frameForItemAtIndexPath:(NSIndexPath *)indexPath {
CGFloat itemWidth = [self itemWidth];
CGFloat itemHeight = [self itemHeight];
CGFloat originX = HORIZONTAL_PAD + ((indexPath.row % NUMBER_OF_ITEMS_PER_ROW)*(HORIZONTAL_PAD + itemWidth));
CGFloat originY = VERTICAL_PAD + (floorf(indexPath.row/NUMBER_OF_ITEMS_PER_ROW)*(VERTICAL_PAD + itemHeight));
return CGRectMake(originX, originY, itemWidth, itemHeight);
}
- (void)prepareLayout {
NSMutableDictionary *newLayoutInfo = [NSMutableDictionary dictionary];
NSMutableDictionary *cellLayoutInfo = [NSMutableDictionary dictionary];
NSInteger sectionCount = [self.collectionView numberOfSections];
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:0];
for (NSInteger section = 0; section < sectionCount; section++) {
NSInteger itemCount = [self.collectionView numberOfItemsInSection:section];
for (NSInteger item = 0; item < itemCount; item++) {
indexPath = [NSIndexPath indexPathForItem:item inSection:section];
UICollectionViewLayoutAttributes *itemAttributes =
[UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
itemAttributes.frame = [self frameForItemAtIndexPath:indexPath];
NSString *key = [self keyForIndexPath:indexPath];
cellLayoutInfo[key] = itemAttributes;
}
}
newLayoutInfo[@"CellKind"] = cellLayoutInfo;
self.layoutInfo = newLayoutInfo;
}
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {
NSString *key = [self keyForIndexPath:indexPath];
UICollectionViewLayoutAttributes *retVal = self.layoutInfo[@"CellKind"][key];
return retVal;
}
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
NSMutableArray *allAttributes = [NSMutableArray arrayWithCapacity:self.layoutInfo.count];
[self.layoutInfo enumerateKeysAndObjectsUsingBlock:^(NSString *elementIdentifier,
NSDictionary *elementsInfo,
BOOL *stop) {
[elementsInfo enumerateKeysAndObjectsUsingBlock:^(NSIndexPath *indexPath,
UICollectionViewLayoutAttributes *attributes,
BOOL *innerStop) {
if (CGRectIntersectsRect(rect, attributes.frame)) {
[allAttributes addObject:attributes];
}
}];
}];
return allAttributes;
}
- (CGSize)collectionViewContentSize {
return CGSizeMake(self.collectionView.bounds.size.width, floorf([self.collectionView numberOfItemsInSection:0]/NUMBER_OF_ITEMS_PER_ROW) * (self.itemHeight + VERTICAL_PAD) + VERTICAL_PAD);
}
in your mainView add:
[[UICollectionView alloc] initWithFrame:self.bounds collectionViewLayout:[[YourOwnCollectionViewLayout alloc] init]];
and you're DONE!
You are not considering the sectionInset
and the interItemSpacing
. It has some default values which pushes the cells(gives padding). Either you can set the interItemSpacing
to 0 and sectionInset
to UIEdgeInsetsZero
or you have to consider their values during calculation of the cellWidth.
Override these protocol methods for setting the size, insets and interItem spacing
optional public func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize
optional public func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int) -> UIEdgeInsets
optional public func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAtIndex section: Int) -> CGFloat
optional public func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAtIndex section: Int) -> CGFloat