這裏的技巧是,我們需要創建定製UICollectionViewFlowLayout
as:
CustomCollectionLayout.h
#import <UIKit/UIKit.h>
@protocol CustomCollectionLayoutDelegate
<UICollectionViewDelegateFlowLayout>
@end
@interface CustomCollectionLayout : UICollectionViewFlowLayout
@end
CustomCollectionLayout.m
#import "CustomCollectionLayout.h"
@interface CustomCollectionLayout()
@end
@implementation CustomCollectionLayout
{
NSDictionary *_layoutInfo;
CGFloat maxColumnHeight;
__weak id<CustomCollectionLayoutDelegate> delegate;
}
- (void)prepareLayout{
delegate = (id<CustomCollectionLayoutDelegate>) self.collectionView.delegate;
//Calculate max values
maxColumnHeight = [self maxColumnHeight];
//Store calculated frames for cells in the dictionary
NSMutableDictionary *cellLayoutInfo = [NSMutableDictionary dictionary];
//Calculate Frame for a cell, per values from DataSource
CGFloat originY = 0;
NSInteger sectionCount = [self.collectionView numberOfSections];
for (NSInteger section = 0; section < sectionCount; section++) {
UIEdgeInsets itemInsets = UIEdgeInsetsZero;
if ([delegate respondsToSelector:@selector(collectionView:layout:insetForSectionAtIndex:)]) {
itemInsets = [delegate collectionView:self.collectionView layout:self insetForSectionAtIndex:section];
originY += itemInsets.top;
}
CGFloat height = 0;
NSInteger itemCount = [self.collectionView numberOfItemsInSection:section];
CGFloat originX = itemInsets.left;
for (NSInteger item = 0; item < itemCount; item++) {
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:item inSection:section];
UICollectionViewLayoutAttributes *itemAttributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
CGSize itemSize = CGSizeZero;
if ([delegate respondsToSelector:@selector(collectionView:layout:sizeForItemAtIndexPath:)]) {
itemSize = [delegate collectionView:self.collectionView layout:self sizeForItemAtIndexPath:indexPath];
float selectedOriginY = originY;
itemAttributes.frame = CGRectMake(originX, selectedOriginY, itemSize.width, itemSize.height);
}
cellLayoutInfo[indexPath] = itemAttributes;
CGFloat interItemSpacingX = 0;
if ([delegate respondsToSelector:@selector(collectionView:layout:minimumInteritemSpacingForSectionAtIndex:)]) {
interItemSpacingX = [delegate collectionView:self.collectionView layout:self minimumInteritemSpacingForSectionAtIndex:section];
}
originX += floorf(itemSize.width + interItemSpacingX);
height = height > itemSize.height ? height : itemSize.height;
}
CGFloat interItemSpacingY = 0;
if ([delegate respondsToSelector:@selector(collectionView:layout:minimumLineSpacingForSectionAtIndex:)]) {
interItemSpacingY = [delegate collectionView:self.collectionView layout:self minimumLineSpacingForSectionAtIndex:section];
}
originY += floor(height + interItemSpacingY);
}
_layoutInfo = cellLayoutInfo;
}
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
NSMutableArray *allAttributes = [NSMutableArray arrayWithCapacity:_layoutInfo.count];
[_layoutInfo enumerateKeysAndObjectsUsingBlock:^(NSIndexPath *indexPath,
UICollectionViewLayoutAttributes *attributes,
BOOL *innerStop) {
if (CGRectIntersectsRect(rect, attributes.frame)) {
[allAttributes addObject:attributes];
}
}];
return allAttributes;
}
- (BOOL) shouldInvalidateLayoutForBoundsChange:(CGRect)newBound
{
return YES;
}
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
return _layoutInfo[indexPath];
}
- (CGSize)collectionViewContentSize
{
CGFloat width = self.collectionView.frame.size.width;
CGFloat height = maxColumnHeight;
return CGSizeMake(width, height);
}
//Maximum Height of perticular Column in CollectionView
- (CGFloat)maxColumnHeight
{
NSInteger sectionCount = [self.collectionView numberOfSections];
CGFloat maxHeight = 0;
for (NSInteger section = 0; section < sectionCount; section++) {
NSInteger itemCount = [self.collectionView numberOfItemsInSection:section];
CGFloat maxRowHeight = 0;
for (NSInteger item = 0; item < itemCount; item++) {
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:item inSection:section];
if ([delegate respondsToSelector:@selector(collectionView:layout:sizeForItemAtIndexPath:)]) {
CGSize itemSize = [delegate collectionView:self.collectionView layout:self sizeForItemAtIndexPath:indexPath];
maxRowHeight = itemSize.height > maxRowHeight ? itemSize.height : maxRowHeight;
}
}
CGFloat interSectionSpacingY = 0;
if ([delegate respondsToSelector:@selector(collectionView:layout:minimumLineSpacingForSectionAtIndex:)]) {
interSectionSpacingY = [delegate collectionView:self.collectionView layout:self minimumLineSpacingForSectionAtIndex:section];
}
UIEdgeInsets itemInsets = UIEdgeInsetsZero;
if ([delegate respondsToSelector:@selector(collectionView:layout:insetForSectionAtIndex:)]) {
itemInsets = [delegate collectionView:self.collectionView layout:self insetForSectionAtIndex:section];
}
maxHeight += maxRowHeight;
//Add interSectionSpacing and Insets for all sections except last.
if (section != sectionCount-1) {
maxHeight += interSectionSpacingY + itemInsets.top;
}
}
return maxHeight;
}
@end
原諒我提供Objective-C
代碼,但我們可以用橋接報
然後使用該自定義佈局:
灰色是集合視圖,而粉紅色是細胞。
委託方法:
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("CollectionCellId", forIndexPath: indexPath)
cell.backgroundColor = UIColor.greenColor()
//cell.lb.text = "Something"
//cell.img.image = UIImage(named: "setting")
cell.layer.borderColor = UIColor.lightGrayColor().CGColor
cell.layer.borderWidth = 1
return cell;
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
let screen = UIScreen.mainScreen().bounds
return CGSize(width: CGFloat(screen.width/3), height: 120)
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAtIndex section: Int) -> CGFloat {
return 0
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAtIndex section: Int) -> CGFloat {
return 0
}
這裏是輸出:
現在,我們可以使用任何自定義單元格並獲得所需的外觀ñ感覺。
希望這會幫助你!
嘗試使用CGFloat((screen.width-(3 * 10))/ 3) –
我試過了,但什麼都沒發生 –