UICollectionView进阶之路(一)

UICollectionView基础

  • UICollectionViewFlowLayout:视图布局对象,继承自UICollectionViewLayout。

所有的视图布局对象都继承自UICollectionViewLayout。若我们要自定义布局对象,我们一般继承UICollectionViewFlowLayout就可以了。

  • 需要实现三个协议;UICollectionViewDataSource(数据源)、UICollectionViewDelegateFlowLayout(视图布局)、UICollectionViewDelegate。

可以看得出,UICollectionView几乎和UITableView一样,但是视图布局和装饰视图让它更强大,UITableView能做到的UICollectionView都能做到,UICollectionView能做到的UITableView不一定能做到(这也是我一直选择UICollectionView的原因之一)。

UICollectionView实现步骤

  1. UICollectionView创建及注册
  2. UICollectionViewDataSource的实现
  3. UICollectionViewDelegateFlowLayout的实现(或者自定义UICollectionViewLayout实现)
  4. UICollectionViewDelegate的实现

熟悉UICollectionView的程序员都知道,实现过程很繁琐,数据源代理看的眼花缭乱,有思想的程序员也许都会在想同样的问题:

  1. 每次都要注册很烦,是不是内部可以根据某个标识判断是否注册及自动注册呢?
  2. 为什么内部不能根据我的数据计算几行几列,创建初始化视图及视图的大小,更高级的自动缓存高度呢?
  3. UICollectionViewDelegateFlowLayout的实现太麻烦了,要是可以不要写那么多该多好啊

我也一样是个有思想的码农(哈哈),一直在寻求可以同时解决这些痛处的方法,一次在和同学的聊天中,和同学聊到了数据即视图的思想,视图的布局都是由数据来驱动的,于是就有了 UICollectionView进阶第一步,(以下都是个人想法,不喜勿喷,有更好的想法可以联系我)

SuperCollectionView

  • SuperCollectionView的结构
SuperUICollectionView结构图.png
  1. SuperCollectionView的发动机(数据):(NSObject+XWReuseData)
@interface NSObject (XW)

/**
 cell或者header,footer的高度,框架自动缓存
 */
@property (nonatomic, assign) CGFloat xw_height;

/**
 cell或者header,footer的宽度,框架自动缓存
 */
@property (nonatomic, assign) CGFloat xw_width;

/**
 cell或者header,footer的重用标识,框架自动缓存(可以为空,有默认值)
 cell的重用标识(默认数据去除Data改为Cell)
 header或者footer的重用标识 (默认数据去除Data改为View)
 */
@property (nonatomic, strong) NSString *reuseIdentifier;

/**
 cell或者header,footer是否重用
 */
@property (nonatomic, assign) BOOL unReusable;

#pragma mark -
#pragma mark - 以下属性只对header或者footer生效
/**
 collectionView每个section的内边距
 */
@property(nonatomic , assign) UIEdgeInsets cell_secionInset;

/**
 collectionView每个section的边距
 */
@property(nonatomic , assign) CGFloat cell_minimumLineSpacing;

/**
 collectionView每个item的边距
 */
@property(nonatomic , assign) CGFloat cell_minimumInteritemSpacing;

@end

数据驱动视图,一个个简单的数据可以拼凑出乎意料的页面,只有你想不到,没有SuperCollectionView做不到的

  1. SuperCollectionView注册:(UICollectionView+XWRegister)
@interface UICollectionView (XWRegister)
/**
 * 注册列表缓存
 */
@property (nonatomic, strong) NSMutableArray *reuseIdentifierList;

-(UICollectionViewCell *)dequeueReusableCellWithIdentify:(NSString *)identify indexPath:(NSIndexPath *)indexPath reusable:(BOOL )reusable;

-(UICollectionReusableView *)dequeueReusableView:(NSString *)identify indexPath:(NSIndexPath *)indexPath kind:(NSString *)kind reusable:(BOOL )reusable;

@end

在XWCollectionViewDataSourceDelegate内完成了缓存重用标识并判断否注册及自动注册

  1. SuperCollectionView对外数据源接口协议
@protocol XWCollectionViewDataSource <NSObject>
@required
/**
 * cell数据源(支持多个section返回值为二重数组即可)
 */
- (NSMutableArray *)cellDataListWithCollectionView:(UICollectionView *)collectionView;
@optional
/**
 *  头部数据源
 */
- (NSMutableArray *)headerDataListWithCollectionView:(UICollectionView *)collectionView;
/**
 *  尾部数据源
 */
- (NSMutableArray *)footerDataListWithCollectionView:(UICollectionView *)collectionView;
/**
 *  每个secion对应的修饰背景view
 */
- (NSMutableArray<Class> *)decorationViewClassListWithCollectionView:(UICollectionView *)collectionView;

@end;

我对UICollectionView的数据源及UICollectionViewDelegateFlowLayout进行了高度封装(详细的见XWCollectionViewDataSourceDelegate),对代理进行了一层转发。

SuperCollectionView实战

看了上面的是不是更加感兴趣了(卧槽,还有这种操作),接下来就是见证奇迹的时刻,让我们一起来看看现在是如何使用UICollectionView的吧


- (void)viewDidLoad {
    [super viewDidLoad];
    [self.view addSubview:self.cv];
    // Do any additional setup after loading the view, typically from a nib.
}
#pragma mark - XWCollectionViewDataSource

-(NSMutableArray *)headerDataListWithCollectionView:(UICollectionView *)collectionView{
    return self.headerDataList;
}

-(NSArray *)cellDataListWithCollectionView:(UICollectionView *)collectionView{
    return [[NSMutableArray alloc] initWithObjects:self.cellDataList,self.cellDataList,self.cellDataList, nil];
}

-(NSMutableArray *)footerDataListWithCollectionView:(UICollectionView *)collectionView{
    return self.footerDataList;
}

-(NSMutableArray<Class> *)decorationViewClassListWithCollectionView:(UICollectionView *)collectionView{
    return self.decroationViewClassList;    
}

#pragma mark - delegate
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
    
}

-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{

}

#pragma mark - getter
-(UICollectionView *)cv{
    if (!_cv) {
        _cv = [UICollectionView createWithFlowLayout];
        _cv.frame = CGRectMake(0, 0, self.view.bounds.size.width, [UIScreen mainScreen].bounds.size.height);
        _cv.backgroundColor = [UIColor whiteColor];
        _cv.xw_dataSource = self;
        _cv.xw_delegate = self;
    }
    return _cv;
}

-(NSMutableArray *)headerDataList{
    if (!_headerDataList) {
        _headerDataList = [NSMutableArray new];
        [_headerDataList addObject:[ACollectionViewHeaderData new]];
        [_headerDataList addObject:[ACollectionViewHeaderData new]];
        NSObject * defaultData = [NSObject new];
        defaultData.cell_width = 0.001;
        defaultData.cell_height = 0.001;
        defaultData.cell_minimumLineSpacing = 10;
        defaultData.cell_minimumInteritemSpacing = 10;
        defaultData.cell_secionInset = UIEdgeInsetsMake(10, 10, 10, 10);
        [_headerDataList addObject:defaultData];
    }
    return _headerDataList;
}
-(NSMutableArray *)cellDataList{
    if (!_cellDataList) {
        _cellDataList = [NSMutableArray new];
        ACollectionViewData * data = [ACollectionViewData new];
        data.color = [UIColor redColor];
        data.title = @"我是cell";
        [_cellDataList addObject:data];
        
        data = [ACollectionViewData new];
        data.color = [UIColor blueColor];
        data.title = @"我是cell";
        [_cellDataList addObject:data];
        
        data = [ACollectionViewData new];
        data.color = [UIColor grayColor];

        data.title = @"我是cell";
        [_cellDataList addObject:data];
        
        data = [ACollectionViewData new];
        data.color = [UIColor cyanColor];

        data.title = @"我是cell";
        [_cellDataList addObject:data];
        
        [_cellDataList addObject:data];
        data = [ACollectionViewData new];
        data.color = [UIColor blueColor];
        data.title = @"我是cell";
        [_cellDataList addObject:data];
    }
    return _cellDataList;
}

可以看出来data起到了很关键的作用,几个简单的data就可以驱动一个UICollectionView,这就是数据即视图,这样UICollectionView进阶之路走出了第一步,几行代码轻轻松松就可以搞定UICollectionView(我上我也行,哈哈)。如果你喜欢你也可以试试这样处理哦~

但这远远还不够,既然你能把数据源代理简化成这样,那你是不是能直接不写数据源代理呢,想想连数据源都不用写了,那是种什么体验啊,是的,没错,下一步要做的就是摒弃数据源(程序员:我不信,哈哈),敬请期待UICollectionView进阶之路(二)。

GitHub: https://github.com/WangJianShi/UICollectionView-Widget

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 162,475评论 4 372
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,744评论 2 307
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 112,101评论 0 254
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,732评论 0 221
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 53,141评论 3 297
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 41,049评论 1 226
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,188评论 2 320
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,965评论 0 213
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,716评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,867评论 2 254
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,341评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,663评论 3 263
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,376评论 3 244
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,200评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,990评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,179评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,979评论 2 279

推荐阅读更多精彩内容