iOS 不规则排列的UICollectionViewcell

  • 内容
  • 评论
  • 相关

首页有一块UI设计的是几个色块,不想用xib在UICollectionViewcell上绘制成死的四个区块,想用UICollectionViewcell写活。
采用了2中方式尝试去实现:

  • UICollectionViewLayout
  • UICollectionViewFlowLayout
    实践证明,UICollectionViewFlowLayout简单点,因为他继承自UICollectionViewLayout,增加了很多属性,使用简单便捷。



1.使用UICollectionViewLayout

#import "CollectionViewLayout.h"
#define getAvailableWidth(w) ((w) - self.sectionInset.left - self.sectionInset.right-10)
#define HorizontalSpace 10
#define VerticalSpace 10

@interface CollectionViewLayout()

/** 保存attribute */
@property (nonatomic,strong) NSMutableArray * attributes;
/** 保存每个Section的最大高度 */
@property (nonatomic,assign) CGFloat  eachSectionHightest;
/** 保存当前section的边距 */
@property (nonatomic,assign) UIEdgeInsets sectionInset;
@end

@implementation CollectionViewLayout

#pragma mark - 懒加载
- (NSMutableArray *)attributes {
    if (_attributes == nil) {
        _attributes = [NSMutableArray new];
    }
    return _attributes;
}

#pragma mark - 系统方法

- (instancetype)init
{
    self = [super init];
    if (self) {

    }
    return self;
}


- (void)prepareLayout {
    [super prepareLayout];
    self.sectionInset = UIEdgeInsetsMake(20, 25, 20, 25);
    self.eachSectionHightest = 0;

    NSInteger section = [self.collectionView numberOfSections];
    for (NSInteger i = 0; i < section; i++) {

        // 计算当前section的每个cell的frame
        NSInteger row = [self.collectionView numberOfItemsInSection:i];
        for (NSInteger j = 0; j < row; j++) {
            NSIndexPath * indexPath = [NSIndexPath indexPathForItem:j inSection:i];
            UICollectionViewLayoutAttributes * attribute = [self layoutAttributesForItemAtIndexPath:indexPath];
            [self.attributes addObject:attribute];
        }
    }
}


- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {
    // 实例化attribute
    UICollectionViewLayoutAttributes * attribute = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];

    NSInteger width = getAvailableWidth(self.collectionView.frame.size.width);
    CGFloat bili1 = 160.00/getAvailableWidth(375);
    CGFloat bili2 = 155.00/getAvailableWidth(375);
    CGFloat bili3 = 325.00/getAvailableWidth(375);

    CGFloat wh_bili1 = 160.00/170;
    CGFloat wh_bili2 = 155.00/80;
    CGFloat wh_bili3 = 325.00/60;

    // 计算attribute的frame
    CGFloat X = 0+self.sectionInset.left;
    CGFloat Y = 0+self.sectionInset.top;


    if (indexPath.row == 0) {
        attribute.frame = CGRectMake(X, Y, width*bili1, width*bili1/wh_bili1);
        self.eachSectionHightest = self.eachSectionHightest+ Y+width*bili1/wh_bili1;
    }else if (indexPath.row == 1){
        attribute.frame = CGRectMake(X+width*bili1+HorizontalSpace, Y, width*bili2, width*bili2/wh_bili2);
    }else if (indexPath.row == 2){
        attribute.frame = CGRectMake(X+width*bili1+HorizontalSpace, Y+width*bili2/wh_bili2+VerticalSpace, width*bili2, width*bili2/wh_bili2);
    }else if (indexPath.row == 3){
        attribute.frame = CGRectMake(X, Y+width*bili1/wh_bili1+VerticalSpace, width*bili3, width*bili3/wh_bili3);
        self.eachSectionHightest = self.eachSectionHightest+VerticalSpace+width*bili3/wh_bili3;
    }
    return attribute;
}


/**
 *  返回特定区域的attribute
 */
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {

    NSMutableArray * array = [NSMutableArray array];

    [self.attributes enumerateObjectsUsingBlock:^(UICollectionViewLayoutAttributes * obj, NSUInteger idx, BOOL * _Nonnull stop) {
        if (CGRectIntersectsRect(rect, obj.frame)) {
            [array addObject:obj];
        }
    }];

    return array;
}

/**
 *  返回scrollView的contentSize
 */
- (CGSize)collectionViewContentSize {
//    NSLog(@"size:%@",NSStringFromCGSize(CGSizeMake(self.collectionView.frame.size.width, self.eachSectionHightest + self.sectionInset.bottom)));
    return CGSizeMake(self.collectionView.frame.size.width, self.eachSectionHightest + self.sectionInset.bottom);

}
@end

2.使用UICollectionViewFlowLayout

#import "CollectionViewFlowLayout.h"
#define getAvailableWidth(w) ((w) - self.sectionInset.left - self.sectionInset.right-10)


@implementation CollectionViewFlowLayout

- (void)prepareLayout{
    [super prepareLayout];
    // 垂直滚动
    self.scrollDirection = UICollectionViewScrollDirectionVertical;

    self.minimumLineSpacing = 0;
    self.minimumInteritemSpacing = 0;
    self.sectionInset = UIEdgeInsetsMake(20, 25, 20, 25);
}


- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect{
    NSArray *array = [super layoutAttributesForElementsInRect:rect];
    for (int i=0; i<array.count; i++){
        UICollectionViewLayoutAttributes * attribute = array[i];

        NSInteger width = getAvailableWidth(self.collectionView.frame.size.width);
        CGFloat bili1 = 160.00/getAvailableWidth(375);
        CGFloat bili2 = 155.00/getAvailableWidth(375);
        CGFloat bili3 = 325.00/getAvailableWidth(375);

        CGFloat wh_bili1 = 160.00/170;
        CGFloat wh_bili2 = 155.00/80;
        CGFloat wh_bili3 = 325.00/60;

        // 计算attribute的frame
        CGFloat X = 0+self.sectionInset.left;
        CGFloat Y = 0+self.sectionInset.top;

        if (i == 0) {
            attribute.frame = CGRectMake(X, Y, width*bili1, width*bili1/wh_bili1);
        }else if (i == 1){
            attribute.frame = CGRectMake(X+width*bili1+10, Y, width*bili2, width*bili2/wh_bili2);
        }else if (i == 2){
            attribute.frame = CGRectMake(X+width*bili1+10, Y+width*bili2/wh_bili2+10, width*bili2, width*bili2/wh_bili2);
        }else if (i == 3){
            attribute.frame = CGRectMake(X, Y+width*bili1/wh_bili1+10, width*bili3, width*bili3/wh_bili3);
        }
    }

    return array;
}




- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds{
    return YES;
}

@end

评论

0条评论

发表评论

邮箱地址不会被公开。