iOS开发之笔记摘录

iOS常用控件之UICollectionView

2019-06-29  本文已影响0人  平安喜乐698
目录
  
1. UICollectionView
    // 1.创建 布局对象
    UICollectionViewFlowLayout *fl=[UICollectionViewFlowLayout new];
    // 设置 滚动方向
    [fl setScrollDirection:UICollectionViewScrollDirectionVertical];
/*
通常使用dele来设置,而不是通过以下:
    // 设置 最小行间距(也可通过dele方法设置)
    [fl setMinimumLineSpacing:10];
    // 设置 最小项间距(也可通过dele方法设置)
    [fl setMinimumInteritemSpacing:10];
    // 设置 项大小(也可通过dele方法设置)
    [fl setItemSize:CGSizeMake(200, 100)];
    // 设置 组内边距(也可通过dele方法设置)
    [fl setSectionInset:UIEdgeInsetsZero];
    // 垂直滚动时 高起作用(宽无效 为collV宽),水平滚动时 宽起作用(高无效 为collV高)
    // 设置 头视图大小(也可通过dele方法设置)
    [fl setHeaderReferenceSize:CGSizeMake(100, 100)];
    // 设置 尾视图大小(也可通过dele方法设置)
    [fl setFooterReferenceSize:CGSizeMake(100, 100)];
*/

    // 2.创建 UICollectionView    : UIScrollView
    UICollectionView *contentCollV=[[UICollectionView alloc]initWithFrame:CGRectZero collectionViewLayout:fl];
    // 设置 dele<UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout>
    [contentCollV setDelegate:self];
    [contentCollV setDataSource:self];
    [self.view addSubview:contentCollV];
    // 3.注册 cell
    [contentCollV registerClass:[] forCellWithReuseIdentifier:NSStringFromClass([])];
    [contentCollV registerNib:[UINib nibWithNibName:@"" bundle:nil] forCellWithReuseIdentifier:@""];
    // 3.注册 head、foot视图
    [contentCollV registerClass:[] forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:NSStringFromClass([])];
    [contentCollV registerNib:[UINib nibWithNibName:@"" bundle:nil] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@""];

/*
    // 删除 指定组
    [contentCollV deleteSections:[NSIndexSet indexSetWithIndex:0]];
    // 删除 指定项
    [contentCollV deleteItemsAtIndexPaths:@[[NSIndexPath indexPathForItem:0 inSection:0]]];
    // 插入 指定组
    [contentCollV insertSections:[NSIndexSet indexSetWithIndex:0]];
    // 插入 指定项
    [contentCollV insertItemsAtIndexPaths:@[[NSIndexPath indexPathForItem:0 inSection:0]]];
    // 获取 指定indexPath对应的项
    UICollectionViewCell *cell=(UICollectionViewCell *)[contentCollV cellForItemAtIndexPath:indexPath];
*/
自定义CELL MyCell: UICollectionViewCell

-(instancetype)initWithFrame:(CGRect)frame{
    self=[super initWithFrame:frame];
    if(self){
        [self setupUI];
    }
    return self;
}

自定义头尾视图 :UICollectionReusableView
// 初始化控件
-(void)applyLayoutAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes{  
}
需求:更新数据源后立刻设置contentOffset

        [self.matchCollectionView reloadData];
        [self.matchCollectionView layoutIfNeeded];  // 如果不加,会导致setContentOffset没效果
        [self.matchCollectionView setContentOffset:CGPointMake(kScreenWidth, 0)];

dele

<UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout>

// 返回 组数
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{return 0;}
// 返回 每组的项数
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{return 0;}
// 返回 每项大小
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{return CGSizeMake(100, 100);}
// 返回 每项
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
    UICollectionViewCell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:@"" forIndexPath:indexPath];
    return cell;
}
// 返回 每项的最小行间距
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section{return CGFLOAT_MIN;}
// 返回 每项的最小列间距
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section{return CGFLOAT_MIN;}
// 返回 组间距
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section{return UIEdgeInsetsZero;}
// 返回 头视图的size
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section{return CGSizeMake(100, 100);}
// 返回 尾视图的size
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section{return CGSizeMake(100, 100);}
// 返回 头视图、尾视图
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath{
    if([kind isEqualToString:UICollectionElementKindSectionHeader]){
        UICollectionReusableView *headV=[collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"" forIndexPath:indexPath];
        return headV;
    }else{
        UICollectionReusableView *footV=[collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"" forIndexPath:indexPath];
        return footV;
    }
    return [UICollectionReusableView new];
}
// 是否允许选择项
- (BOOL)collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath{return true;}
// 选择某项后调用
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{}
// 是否允许反选项
- (BOOL)collectionView:(UICollectionView *)collectionView shouldDeselectItemAtIndexPath:(NSIndexPath *)indexPath{return true;}
// 反选某项后调用
- (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath{}
// 是否 允许项高亮
- (BOOL)collectionView:(UICollectionView *)collectionView shouldHighlightItemAtIndexPath:(NSIndexPath *)indexPath{return true;}
// 项高亮后调用
- (void)collectionView:(UICollectionView *)collectionView didHighlightItemAtIndexPath:(NSIndexPath *)indexPath{}
// 项反高亮后调用
- (void)collectionView:(UICollectionView *)collectionView didUnhighlightItemAtIndexPath:(NSIndexPath *)indexPath{}
// 是否允许移动项
- (BOOL)collectionView:(UICollectionView *)collectionView canMoveItemAtIndexPath:(NSIndexPath *)indexPath{return true;}
// 移动项后调用
- (void)collectionView:(UICollectionView *)collectionView moveItemAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath*)destinationIndexPath{}
// 返回 索引
- (NSArray<NSString *> *)indexTitlesForCollectionView:(UICollectionView *)collectionView{return @[@"A",@"B"];}
// 返回 索引下标
- (NSIndexPath *)collectionView:(UICollectionView *)collectionView indexPathForIndexTitle:(NSString *)title atIndex:(NSInteger)index{}
// 长按时是否显示菜单
- (BOOL)collectionView:(UICollectionView *)collectionView shouldShowMenuForItemAtIndexPath:(NSIndexPath *)indexPath{return true;}
// 是否允许某操作
- (BOOL)collectionView:(UICollectionView *)collectionView canPerformAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(nullable id)sender{return true;}
// 进行某种操作时调用
- (void)collectionView:(UICollectionView *)collectionView performAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(nullable id)sender{}
// 即将显示项时调用
- (void)collectionView:(UICollectionView *)collectionView willDisplayCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath{}
// 即将显示头尾视图时调用
- (void)collectionView:(UICollectionView *)collectionView willDisplaySupplementaryView:(UICollectionReusableView *)view forElementKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath{}
// 结束显示项时调用
- (void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath{}
// 结束显示头尾视图时调用
- (void)collectionView:(UICollectionView *)collectionView didEndDisplayingSupplementaryView:(UICollectionReusableView *)view forElementOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath{}
  1. 流布局

部分代码如下:

1.布局类

YTMyCollectionViewFL.h

#import <UIKit/UIKit.h>
@protocol YTMyCollectionViewFLDele <NSObject>
-(CGFloat)heightWithindexPath:(NSIndexPath *)indexPath;
@end

@interface YTMyCollectionViewFL : UICollectionViewFlowLayout
@property (nonatomic,weak) id<YTMyCollectionViewFLDele> dele;
@end

YTMyCollectionViewFL.m

#import "YTMyCollectionViewFL.h"
#import "YTMyCollectionViewFL.h"
#import "YTMyCollVFLTool.h"

@interface YTMyCollectionViewFL()


@property (nonatomic,assign) CGFloat columnMargin;      // 行间距
@property (nonatomic,assign) CGFloat rowMargin;         // 列间距
@property (nonatomic,assign) CGFloat columnNum;         // 列数
@property (nonatomic,assign) CGFloat width;
@property (nonatomic,assign) UIEdgeInsets sectionInsets;

@property (nonatomic,strong) NSMutableDictionary *maxYDic;  // 存储每列maxY

@property (nonatomic,strong) NSMutableArray *attributeArr;  // 存储所有att布局属性
@end


@implementation YTMyCollectionViewFL


// collV不用遵循flowlayoutDele,不用实现sizefor/sectionInset
-(instancetype)init{
    
    //
    self=[super init];
    if(self){
    
        YTMyCollVFLTool *tool=[YTMyCollVFLTool sharedTool];
        //
        _columnNum=tool.columnNum;
        _columnMargin=tool.columnMargin;
        _rowMargin=tool.rowMargin;
        _sectionInsets=tool.sectionInsets;
        
    }
    
    return self;
}
// 布局前调用
-(void)prepareLayout{

    [super prepareLayout];
    
    // 初始化maxYDic
    for(int i=0;i<_columnNum;i++){
    
        NSString *column=[NSString stringWithFormat:@"%d",i];
        self.maxYDic[column]=@(_sectionInsets.top);
    }
    
    // 初始化attArr
    [self.attributeArr removeAllObjects];
    NSInteger count=[self.collectionView numberOfItemsInSection:0];
    for(int i=0;i<count;i++){
    
        UICollectionViewLayoutAttributes *att=[self layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0]];
        [self.attributeArr addObject:att];
    }
}

// 返回 总size
-(CGSize)collectionViewContentSize{

    //
    __block NSString *maxColumn=@"0";
    [_maxYDic enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
        if([_maxYDic[maxColumn] floatValue]<[obj floatValue]){
        
            maxColumn=(NSString *)obj;
        }
    }];
    return CGSizeMake(0, [_maxYDic[maxColumn] floatValue]+_sectionInsets.bottom);
}

// 返回 indexPath对应item的布局属性
-(UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath{

    // 每列宽
    _width=(self.collectionView.frame.size.width-_sectionInsets.left-_sectionInsets.right-_columnMargin*(_columnNum-1))/_columnNum;
    
    // height
    CGFloat height=[self.dele heightWithindexPath:indexPath];
    
    // 获取最短列
    __block NSString *minColumn=@"0";
    [_maxYDic enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
        if([obj floatValue]<[_maxYDic[minColumn] floatValue]){
            minColumn=(NSString *)key;
        }
    }];
    // (x,y)
    CGFloat x=_sectionInsets.left+(_columnMargin+_width)*[minColumn floatValue];
    CGFloat y=[_maxYDic[minColumn]floatValue]+_rowMargin;
    // update maxYDic
    _maxYDic[minColumn]=@(y+height);
    
    
    //
    UICollectionViewLayoutAttributes *att=[UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
    att.frame=CGRectMake(x, y, _width, height);
    
    return att;
}

// 返回 rect对应的布局属性
-(NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect{

    return self.attributeArr;
}


-(NSMutableArray *)attributeArr{

    if(!_attributeArr){
        _attributeArr=[NSMutableArray arrayWithCapacity:10];
    }
    return _attributeArr;
}
-(NSMutableDictionary *)maxYDic{

    if(!_maxYDic){
        _maxYDic=[NSMutableDictionary new];
    }
    return _maxYDic;
}
@end

2.工具类

YTMyCollVFLTool.h

@interface YTMyCollVFLTool : NSObject
@property (nonatomic,assign) CGFloat columnMargin;      // 行间距
@property (nonatomic,assign) CGFloat rowMargin;         // 列间距
@property (nonatomic,assign) CGFloat columnNum;         // 列数
@property (nonatomic,assign) UIEdgeInsets sectionInsets;    //
+(instancetype)sharedTool;
@end

YTMyCollVFLTool.m

#import "YTMyCollVFLTool.h"

@implementation YTMyCollVFLTool


static YTMyCollVFLTool *sharedTool;
+(instancetype)sharedTool{
    
    @synchronized (self) {
        if(!sharedTool){
            sharedTool=[YTMyCollVFLTool new];
        }
    }
    
    return sharedTool;
}


-(instancetype)init{

    self=[super init];
    if(self){
    
        //
        _columnNum=2;
        _columnMargin=10;
        _rowMargin=10;
        _sectionInsets=UIEdgeInsetsMake(10, 15, 10, 15);
        
    }
    
    return self;
}
@end

3.使用

   //
   YTMyCollectionViewFL *fl=[YTMyCollectionViewFL new];
   fl.dele=self;
   fl.scrollDirection=UICollectionViewScrollDirectionVertical;

   //
   UICollectionView *contentCollV=[[UICollectionView alloc]initWithFrame:CGRectZero collectionViewLayout:fl];
   _guideCollV=contentCollV;
   [contentCollV setTag:303];
   [contentCollV setBackgroundColor:[UIColor whiteColor]];
   contentCollV.delegate=self;
   contentCollV.dataSource=self;
   [self addSubview:contentCollV];
   [contentCollV autoPinEdgesToSuperviewEdgesWithInsets:UIEdgeInsetsZero];
   
   [contentCollV registerClass:[YTRecomGuideCollectionViewCell class] forCellWithReuseIdentifier:NSStringFromClass([YTRecomGuideCollectionViewCell class])];


-(CGFloat)heightWithindexPath:(NSIndexPath *)indexPath{
   return [_dele heightWithindexPath:indexPath withCollV:_guideCollV];
}
上一篇 下一篇

猜你喜欢

热点阅读