tableViewCell 中嵌套 CollectionView注意事项

引言

最近在做一个 App 是视频类的 初步做出来的效果:

初步效果图

就是上面这样··(表示图好大)

在试了几种方法最后,选择了用在tableViewCell 中嵌套 CollectionView的方法。

须知

1.得先清楚CollectionView创建的步骤(非xib)

因为是在要嵌套到tableViewCell 里边创建 所以 代理是必须的

<UICollectionViewDataSource,UICollectionViewDelegate>

定义布局对象也是必须的

    //创建布局对象
    UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];

之后就是初始化collectView和布局对象

 //创建集合视图(需要布局对象进行初始化)
    self.collectView = [[UICollectionView alloc] initWithFrame:[UIScreen mainScreen].bounds collectionViewLayout:layout];

布局(以下只是一部分还有很多 不一一赘述)

    //确定item的大小
    layout.itemSize = CGSizeMake(100, 120);
    
    //确定横向间距
    layout.minimumLineSpacing = 10;
    
    //确定纵向间距
    layout.minimumInteritemSpacing = 10;
    
    //确定距离上左下右的距离
    layout.sectionInset = UIEdgeInsetsMake(10, 10, 10, 10);
    

    
    //头尾部高度
    layout.headerReferenceSize = CGSizeMake(10, 10);
    layout.footerReferenceSize = CGSizeMake(10, 10);
    
        //确定滚动方向
    layout.scrollDirection = 0;

设置代理也是必须的

        //设置集合视图代理
    self.collectView.delegate = self;
    self.collectView.dataSource = self;

把CollectionView 放到 cell上

    [self addSubview:self.collectView];

以上内容写在自定义的cell中的

//注册方法1
    [self.tableView registerNib:[UINib nibWithNibName:@"   " bundle:nil] forCellReuseIdentifier:@" "];
//写在cell的
- (void)awakeFromNib {
    [super awakeFromNib];
    // Initialization code
}

//注册方法2
    [self.tableView registerClass:<#(nullable Class)#> forCellReuseIdentifier:<#(nonnull NSString *)#>]
//在cell重写一个初始化方法
//  在分配数据前 调用

之后就是代理方法了 (必须的两个)

//元素个数
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
    return 0;
}
//数据分配
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
    CollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@" " forIndexPath:indexPath];
    
    
    return cell;
}

tableViewCell使用xib布局时的差别

首先

xib图

在tableViewCell.xib上拖入CollectionView
这里与纯代码的差别是:
不需要在自行设置 布局对象UICollectionViewFlowLayout
宽高 上下左右间隔都可以在边调动 很直观
cell size 设置宽高
section lnsets 设置与边框间隔
min spacing 设置元素间隔

但使用起来不能达到真正的自适应
屏幕宽度改变(6和6plus) 因为设死了元素的宽 所以间隔会不一样
而且设置的数值与真实数值有偏差 如果使用元素宽自适应cell高度时会有问题
ps:在这种状态下也是需要设置代理的

MVC 模式下的传值

简单效果图

从最开始的tableViewController 开始
一开始收到的数据大概是这样的

[
{
    "titel":2013
    "itmes":[
             {data}
             ]
}
{
    "titel":2011
    "itmes":[
             {data},
             {data},
             {data},
             {data},
             {data}
            ]
}
]

先把每一年的东西打包放入数组

        NSArray *arr = [{
    "titel":2013
    "itmes":[
             {data}
             ]
}
{
    "titel":2011
    "itmes":[
             {data},
             {data},
             {data},
             {data},
             {data}
            ]
}]

//创建Model 继承NSObject
//在.h中设置对应属性
@property (nonatomic, strong) NSDictionary *items;
//网络请求需要在.m加
- (void)setValue:(id)value forUndefinedKey:(NSString *)key{
    
}
        for (NSDictionary *dic in arr) {
//装进model
            Model *model = [[ScreeningTableModel alloc] init];
            [model setValuesForKeysWithDictionary:dic];
//所有model放入数组
            [self.dataArr addObject:model];
        }

//分配数据

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//对应cell 的.h文件里要吧 Model写成属性
//@property (nonatomic, strong) Model *model;
    XMVarietyScreeningTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"screening" forIndexPath:indexPath];
    
//调用 model的set方法 每次调用都会传值
    cell.model = self.dataArr[indexPath.row];
    
    return cell;
}

自定义model的set方法 (tableViewCell中)
- (void)setModel:(Model *)model{
    if (_model != model) {
        _model = model;
        每次调用都会接收到值
        //收到的是一个年份的数据
        //self.model.items 里边有对应年的times里的数据
//初始化数组 tableViewCell里的每次都要初始化
 self.dataArr = [NSMutableArrayy array];
                for (NSDictionary *dic in self.model.items) {
  // 这样每个元素的信息都会装到数组里
//装进model2 
            Model2 *model = [[ScreeningTableModel alloc] init];
            [model setValuesForKeysWithDictionary:dic];
//所有model放入数组
            [self.dataArr addObject:model];
                 }
  //多个tableView 需要收到数据后需要刷新CollectionView
        dispatch_async(dispatch_get_main_queue(), ^{
            [self.CollectionView reloadData];
        });
          }
    }

//分配到CollectionViewCell
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
    XMStarShowCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"show" forIndexPath:indexPath];
       cell.model = self.dataArr[indexPath.row];
    return cell;
}

//CollectionViewCell cell上的分配 这里也是最后的地方了 把得到的数据放到对应的控件上就好了 O(∩_∩)O~~
- (void)setVariety:(StarItmes *)variety{
    if (_variety != variety) {
        _variety = variety;
        //封面图片
        [self.imageView sd_setImageWithURL:[NSURL URLWithString:self.variety.images[@"poster"][@"url"]]];
        //封面信息
        self.timeL.text = self.variety.hint[@"left"];
        //片名
        self.titelL.text = self.variety.title;
        self.introL.text = self.variety.sub_title;
    }
}

当然这样的效果是没有自定义tableViewCell的高度 没法像上边那个图一样tableViewCell的高度不一样
自适应高度 :
1.需要做到的就是传值 , 你需要计算有多少个元素 这么多个元素会占几行 简单的 用 count / 一行的个数计算 或者 用宽来算 (用宽来算比较好看 反正本强迫症是这么认为的 因为能够在所有屏幕上实现自适应 每个的宽 和间隔都 是一样的`` 但要求纯代码 因为XIB布局出来你无法要到精确的间隔宽)
2.需要注意一定要在数据传过来后再算
3.记得刷新tableViewController (在传值时把Controller的地址传过来 不然刷新没用不是同一个东西)
4.tableViewCell太多的时候看不到的cell在你拖动时才开始加载 所以数组需要每次使用前初始化
5.如果以上都做好的 接收数据方面没有出现问题 然后在分配CollectionViewCell数据是总是崩溃出现数组越界的提示在

//这个地方     
  cell.model = self.dataArr[indexPath.row];

这是在自适应tableViewCell高度后会出现的 东西一多就会 改变高度时tableView需要刷新 接收数据时tableViewCell中的CollectionView需要刷新 所以滑动tableView时就出现了问题(具体表示懵逼 ) 所以在确认传过来的数据没有错的情况下可以直接用

 //就是这么粗暴
    if (indexPath.row < self.itemArr.count) {
          cell.model = self.dataArr[indexPath.row];
    }

表示如果有大神路过可以科普一下····

16年 8月17日 随笔········

(@ο@) 哇~ 我又诈尸了!
声明几点东西吧~
1、因为工作原因没弄iOS的Ui好久了 现在mvvm我都没得看过 原生SDK和底层接口倒是看了不少!以前的项目早交了 也没有时间弄 所以呢demo是么有的了~
2、我看了蛮多留言的,现在还需要这个东西的朋友给你们指指路 好好去看 UITableView重用机制 和 用UICollectionView实现瀑布流
3、像什么UITableView需要返回主线程刷新呀 都是蛮基础的了 新学的朋友多碰到几次多问问度娘就知道了,写这东西都是去年的事了 现在回来看感觉跟不上时代了~
4、要元旦了! 大家新年快乐? (づ ̄ 3 ̄)づ (嘿嘿嘿放假了!)

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

推荐阅读更多精彩内容