美文网首页
collectionView流水线性布局(自定义)

collectionView流水线性布局(自定义)

作者: geekAppke | 来源:发表于2018-10-23 21:57 被阅读14次
FlowLayout
    适合cell样式固定、宽度一致
    cell宽度不一致,可以返回每个cell的size,但cell之间的间距还是不确定
    `minimumInteritemSpacing`是最小的间距,每一行间距相等!

自定义LineLayout
    cell的宽度不一致,cell之间的间距相等

不用设置delegate,内部固定
代码geekObjective-C/07-LineLayout

- (void)awakeFromNib {
    [super awakeFromNib];
    [self.collectionView registerNib:[UINib nibWithNibName:NSStringFromClass([BNSearchHistoryCell class]) bundle:nil] forCellWithReuseIdentifier:@"history"];
    _layout.sectionInsets = UIEdgeInsetsMake(0, 10, 10, 0);
    _layout.lineSpacing = 10;
    _layout.interitemSpacing = 10;
}

#pragma mark - BNCollectionViewLineLayoutDelegate
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
    NSString *title = self.historys[indexPath.item];
    // 文字的高和宽
    CGSize size = [title sizeWithFontSize:12 maxSize:CGSizeMake(MAXFLOAT, MAXFLOAT)];
    // 根据文字高和宽在自己增加些范围,使之较为美观
//    return CGSizeMake(size.width + 24, size.height + 12);
    return CGSizeMake(size.width + 24, 29);
}

BNCollectionViewLineLayout

#import <UIKit/UIKit.h>
@protocol BNCollectionViewLineLayoutDelegate <NSObject>
@required
/// 返回cell大小
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath;
@end

@interface BNCollectionViewLineLayout : UICollectionViewLayout

@property (nonatomic,weak) id<BNCollectionViewLineLayoutDelegate> delegate;
/// 距离上下左右的距离
@property (nonatomic,assign) UIEdgeInsets sectionInsets;
/// 上下两个item的距离
@property (nonatomic,assign) CGFloat lineSpacing;
/// 左右两个item的距离
@property (nonatomic,assign) CGFloat interitemSpacing;
@end


#import "BNCollectionViewLineLayout.h"
@interface BNCollectionViewLineLayout ()
{
    // 可滚动内容大小
    CGSize _contentSize;
}
/// 保存cell详细信息
@property (nonatomic,strong) NSMutableArray *itemAttributes;
@end

@implementation BNCollectionViewLineLayout
- (instancetype)init {
    self = [super init];
    if (self) {
        // 设置默认信息
        _sectionInsets = UIEdgeInsetsZero;
        _interitemSpacing = 10;
        _lineSpacing = 10;
    }
    return self;
}

/// 1.布局cell的
- (void)prepareLayout {
    self.delegate = (id<BNCollectionViewLineLayoutDelegate>)self.collectionView.delegate;
    _itemAttributes = [NSMutableArray array];
    
    // cell的x, y, 宽度, 高度
    CGFloat xOffset = _sectionInsets.left;
    CGFloat yOffset = _sectionInsets.top;
    
    // 获取指定组的cell的个数
    NSInteger numberOfItems = [self.collectionView numberOfItemsInSection:0];
    
    // collectionView的宽
    CGFloat collectionViewWidth = self.collectionView.frame.size.width;
    
    // 计算每个cell的位置
    for (int i = 0; i < numberOfItems; i++) {
        NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0];
        // 获取cell的大小
        CGSize size = [self.delegate collectionView:self.collectionView layout:self sizeForItemAtIndexPath:indexPath];
        
        CGFloat maxX = xOffset + size.width;
        if (maxX  > collectionViewWidth - _sectionInsets.right) {
            xOffset = _sectionInsets.left;
            yOffset += size.height + _lineSpacing;
        }
        // 创建一个item的attribute对象
        UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
        // 当前cell坐标
        attributes.frame = CGRectMake(xOffset, yOffset, size.width, size.height);
        
        // 保存cell信息
        [self.itemAttributes addObject:attributes];
        xOffset += size.width + _interitemSpacing;
        
        // 内容总高度
        _contentSize.height = yOffset + size.height + _sectionInsets.bottom;
    }
    _contentSize.width = collectionViewWidth;
}

/// 返回指定范围的cell的布局的详细信息
- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect {
    return self.itemAttributes;
}

/// 返回指定cell的详细布局信息
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {
    return self.itemAttributes[indexPath.item];
}

/// 重新计算当前滚动视图的contentSize
- (CGSize)collectionViewContentSize {
    return _contentSize;
}
FlowLayout
LineLayout

相关文章

网友评论

      本文标题:collectionView流水线性布局(自定义)

      本文链接:https://www.haomeiwen.com/subject/ocdzzftx.html