美文网首页
类似于秒拍的自定义UICollection布局

类似于秒拍的自定义UICollection布局

作者: 未来可期me | 来源:发表于2017-06-01 14:30 被阅读103次
    我们很容易的可以获取到多个,一模一样的UICoectionCell,但是经常见到的一些视屏类应用的cell都是不一样大小的,面对这种情况,其实我们可以自定义UICollection的一个属性UICollectionViewFlowLayout,这本身就是一个UIColection的布局类
    下面直接上代码:
    1.自定义的 DG_CollectionFlowLayout
    .h文件
    #import <UIKit/UIKit.h>
    @class DG_CollectionFlowLayout;
    @protocol  DG_CollectionFlowLayoutDelegate
    @required
    **//计算高度**
    - (CGFloat)CollectionFlowLayout:(DG_CollectionFlowLayout*)DG_CollectionFlowLayout heightForWidth:(CGFloat)width indexPath:(NSIndexPath *)indexpath;
    @end
    @interface DG_CollectionFlowLayout : UICollectionViewFlowLayout
    **//每一行的间距 (row 行 column列 margin间距)**
    @property (nonatomic, assign)CGFloat rowMargin;
    //列间距
    @property (nonatomic, assign)CGFloat columnMargin;
    //允许的最大的列数
    @property (nonatomic, assign)CGFloat columnCount;
    //四边间距
    @property (nonatomic, assign)UIEdgeInsets sectionInset;
    //实现DG_CollectionFlowLayout协议
    @property (nonatomic, assign)id <DG_CollectionFlowLayoutDelegate>delegate;
    
    .m文件
    #import "DG_CollectionFlowLayout.h"
    @interface DG_CollectionFlowLayout ()
    @property (nonatomic, strong)NSMutableDictionary *maxYDict;
    //存放布局属性
    @property (nonatomic ,strong)NSMutableArray *attrsArr;
    @end
    @implementation DG_CollectionFlowLayout
    - (instancetype)init {  
    if ([super init]) {       
      self.columnMargin = 10;     
      self.rowMargin = 10;    
      self.sectionInset = UIEdgeInsetsMake(10, 10, 10, 10);    
      self.columnCount = 2;  //最大列数
      }  
    return self;
    }
    - (NSMutableDictionary *)maxYDict {  
      if (!_maxYDict) {      
           _maxYDict = [NSMutableDictionary dictionary];  
           for (int i = 0; i< self.columnCount; i++) {       
                NSString *column = [NSString stringWithFormat:@"%d",i];    
                self.maxYDict[column] = @"0";      
            } 
       } 
      return _maxYDict;
    }
    - (NSMutableArray *)attrsArr {   
         if (!_attrsArr) {       
             _attrsArr = [NSMutableArray array];
         }   
     return _attrsArr;
    }
    ***#pragma mark 以下方法每次滑动都会调用***
    - (void)prepareLayout {   
        for (int i = 0; i < self.columnCount; i++) {   
        NSString *column = [NSString stringWithFormat:@"%d",i];    
        self.maxYDict[column] = @(self.sectionInset.top);
       }   
       [self.attrsArr removeAllObjects];      
       //1.查看共有多少元素   
       NSInteger count = [self.collectionView numberOfItemsInSection:0];  
       //2.遍历每一个item属性  
    for (int i = 0; i < count; i++) {     
        //取出布局属性       
          UICollectionViewLayoutAttributes *attr = [self layoutAttributesForItemAtIndexPath:   [NSIndexPath indexPathForItem:i inSection:0]];   
        //4.添加到数组中    
      [self.attrsArr addObject:attr]; 
      }}
    
    **//设置允许每个collectionView的content的宽,高**
    //这个方法会被调用两次 prepareLayout方法后调一次 layoutAttributesForElementsInRect:方法后会再调用一次
    - (CGSize)collectionViewContentSize {   
    __block NSString *maxColumn= @"0";   
    [self.maxYDict enumerateKeysAndObjectsUsingBlock:^(NSString *column, NSNumber *maxY, BOOL * stop) {    
      if ([maxY floatValue] > [self.maxYDict[maxColumn] floatValue]) {  
            maxColumn = column;      
    }    }];      
    return CGSizeMake(0, [self.maxYDict[maxColumn] floatValue] + self.sectionInset.bottom);
    }
    ***//允许查找集合视图的布局***
    -(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds{ 
      return YES;
    }
    **/** * **
    **在这个方法里实现布局 * * **
    **@param indexPath 指定的为位置 * * **
    **@return  返回layout attributes 的实例**
    ** */**
    - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath{       
    __block NSString *miniColumn = @"0";  
    [self.maxYDict enumerateKeysAndObjectsUsingBlock:^(NSString *column, NSNumber *maxY, BOOL * stop) {     
      if ([maxY floatValue] < [self.maxYDict[miniColumn] floatValue]) {  
            miniColumn = column;   
        }        
      }];       
        //计算frame 
      CGFloat width = (CGRectGetWidth(self.collectionView.frame) - self.sectionInset.left - self.sectionInset.right - self.columnMargin * (self.columnCount - 1))/self.columnCount;   
      CGFloat height = [self.delegate CollectionFlowLayout:self heightForWidth:width indexPath:indexPath];   
    CGFloat x = self.sectionInset.left + (width + self.columnMargin)*[miniColumn intValue];   
    CGFloat y = [self.maxYDict[miniColumn] floatValue] + self.rowMargin;   
    self.maxYDict[miniColumn] = @(height + y);    
      UICollectionViewLayoutAttributes *attr = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath]; 
      attr.frame = CGRectMake(x, y, width, height);        
      return attr;
    }
    **//设置每个 cell的大小及位置**
    -(NSArray*)layoutAttributesForElementsInRect:(CGRect)rect{
    return self.attrsArr;
    }
    @end
    2.上面两个文件,自定义的布局类DG_CollectionFlowLayout就搞定了,接下来我们自己定义CollectionCell
    #import<UIKit/UIKit.h>
    @interface DGCollectionCell : UICollectionViewCell
    @property (nonatomic, strong)UILabel *titleLabel;
    @property (nonatomic, strong)UILabel *createTimeLabel;
    @property (nonatomic, strong)UIImageView *themeImageView;
    @end
    
    #import "DGCollectionCell.h"
    @implementation DGCollectionCell
    - (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
    _titleLabel = [[UILabel alloc] init];
    _titleLabel.backgroundColor = [UIColor blackColor];
    _titleLabel.alpha = 0.4;
    _titleLabel.text = @"美女";
    _titleLabel.textColor = [UIColor whiteColor];
    
    _createTimeLabel = [[UILabel alloc]init];
    _createTimeLabel.backgroundColor = [UIColor blackColor];
    _createTimeLabel.alpha = 0.4;
    _createTimeLabel.text = @"2015-11-4 17:23";
    _createTimeLabel.textColor = [UIColor greenColor];
    
    _themeImageView = [[UIImageView alloc]init];
    _themeImageView.image = [UIImage imageNamed:@"meinv.jpg"];
    
    [self.contentView addSubview:_themeImageView];
    [self.contentView addSubview:_titleLabel];
    [self.contentView addSubview:_createTimeLabel];
    }
    return self;
    }
    /**
    *  在这里可以布局contentView里面的控件
    *
    *  @param layoutAttributes 直接继承于NSObject 形式上类似于CALayer
    */
    - (void)applyLayoutAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes {
           _themeImageView.frame = CGRectMake(0, 0, layoutAttributes.frame.size.width, layoutAttributes.frame.size.height);
    _titleLabel.frame = CGRectMake(0, layoutAttributes.frame.size.height-42, layoutAttributes.frame.size.width, 21);
    _createTimeLabel.frame = CGRectMake(0, CGRectGetMaxY(_titleLabel.frame), layoutAttributes.frame.size.width, 21);
    }
    @end
    3.最重要的还是怎么用,应该不难,注释也很清楚
    #import "ViewController.h"
    #import "DGCollectionCell.h"#import "DG_CollectionFlowLayout.h"
    @interface ViewController ()
    @property (nonatomic, strong) UICollectionView *collectionView;
    @end
    @implementation ViewController
    - (void)viewDidLoad {
    [super viewDidLoad];
    [self initCollectionView];
    // Do any additional setup after loading the view, typically from a nib.
    }
    - (void)initCollectionView {
    **DG_CollectionFlowLayout *flowLayout = [[DG_CollectionFlowLayout alloc] init];**
    **flowLayout.delegate = self;**
    self.collectionView = [[UICollectionView alloc] initWithFrame:self.view.frame collectionViewLayout:**flowLayout**];
    self.collectionView.backgroundColor = [UIColor redColor];
    self.collectionView.delegate = self;
    self.collectionView.dataSource = self;
    [self.view addSubview:self.collectionView];
    [self.collectionView registerClass:[DGCollectionCell class] forCellWithReuseIdentifier:@"cell"];
    }
    **//下面是我们自定义布局类的代理方法**
    **- (CGFloat)CollectionFlowLayout:(DG_CollectionFlowLayout *)DG_CollectionFlowLayout heightForWidth:(CGFloat)width indexPath:(NSIndexPath *)indexpath {**
    **if (indexpath.row%3==0) {**
    **return 100;**
    **} else if (indexpath.row%3 == 1) {**
    **return 150;**
    **} else {**
    **return 200;**
    **}**
    **}**
    - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    return 25;
    }
    - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    DGCollectionCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath];
    cell.backgroundColor = [UIColor grayColor];
    return cell;
    }
    - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
    NSLog(@"当前选中的item 是 %ld",(long)indexPath.row);
    }
    
    

    效果图如下:

    [点我获取源码]https://pan.baidu.com/s/1pLCxlQb

    相关文章

      网友评论

          本文标题:类似于秒拍的自定义UICollection布局

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