iOS UITableViewCell中包含UICollectionView

最近公司需要修改主界面,把以前所有服务类型都统一类型显示改为分模块化显示。也就造成以前用一个collectionView解决的事情,需要使用到UITableViewCell给不同类型的服务分组。每一个cell中的服务个数又不确定,只能TableViewCell种嵌套UICollectionView。

步骤 1. 使用xib来定义一个cell,用UICollectionView来填充这个cell, 使用上下左右约束来根据不同高度的collectionView 撑起这个cell.


屏幕快照 2018-06-03 下午3.32.36.png

步骤2. 在xib中设置UICollection的属性,如 scroll Direction 设置为Vertical 垂直显示。 Scrolling Enable设置为NO。


屏幕快照 2018-06-03 下午3.33.17.png

在代码中设置属性

 UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc]init];
    flowLayout.minimumInteritemSpacing = 2.0;
    flowLayout.minimumLineSpacing = 1.0f;
//    flowLayout.itemSize = CGSizeMake(DEVICEWIDTH/4.0-0, DEVICEWIDTH/4.0-8);
//    [flowLayout setScrollDirection:UICollectionViewScrollDirectionVertical];
    
    //设置代理
    self.collectionView.delegate = self;
    self.collectionView.dataSource = self;
    
//    self.collectionView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
    self.collectionView.backgroundColor = [UIColor whiteColor];
    [self.collectionView registerClass:[NTNewOfficeServicCollectionCell class] forCellWithReuseIdentifier:@"collectionCell"];
    
    [self.collectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"reusableView"];

步骤3. 在tableViewCell中设置collectionView 的 dataSource Delegate等。

#pragma mark -- UICollectionDataSource
#pragma mark -- UICollectionViewDataSource
//定义展示的UICollectionViewCell的个数
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return self.serviceListArr.count;
}

//定义展示的Section的个数
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
    return 1;
}


//
//每个UICollectionView展示的内容
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    NTNewOfficeServicCollectionCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"collectionCell" forIndexPath:indexPath];
    [cell sizeToFit];
    NTSubscribeModel *model = self.serviceListArr[indexPath.row];
    NSString *serViceIconName = [model.iconIOS lastPathComponent];
    NSString *imageName = [[serViceIconName componentsSeparatedByString:@"@3x"] firstObject];
    [cell.imageView downloadImageBycontentUrlStr:model.iconIOS andIsCut:NO placeholdImage:[UIImage imageNamed:[NSString stringWithFormat:@"newOffice_%@",imageName]] options:SDWebImageRefreshCached];
    //SW:  cacheType = SDImageCacheTypeMemory && SDWebImageRefreshCached   内存缓存 && 重新下载刷新缓存, 频繁reloadData 将导致内存持续增加
    cell.textName.text = model.serviceName;
    model = nil;
    return cell;
}


//头部展示的内容
-(UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
    UICollectionReusableView *headView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"reusableView" forIndexPath:indexPath];
    
    return headView;
}

//定义每个UICollectionView 的大小
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
    return CGSizeMake((DEVICEWIDTH-20-15)/4.0f, DEVICEWIDTH/4.0f-5);
}

//定义每个UICollectionView 的间距
-(UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
{
    return UIEdgeInsetsMake(5, 10, 5, 10);
}

//每个item之间的间距
- (CGFloat)collectionView:(UICollectionView *)collectionView
                   layout:(UICollectionViewLayout*)collectionViewLayout
minimumInteritemSpacingForSectionAtIndex:(NSInteger)section
{
    return 2;
}


////动态设置每列的间距大小
//- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
//    return 1.0f;
//}

//
//UICollectionView被选中时调用的方法
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
    NTSubscribeModel *model = self.serviceListArr[indexPath.row];
    if(self.newOfficeServiceWasSelect){
        self.newOfficeServiceWasSelect(model, indexPath.row, self);
    }
}

步骤4. 当在tableView中获取到数据时,刷新UitableView , 把需要显示的数据赋值给tableViewCell, 在使用collectionView realoadData, 刷新collectView.

NTNewOfficeServiceCell *cell = [tableView dequeueReusableCellWithIdentifier:NEWIMPORTSERVICECELL forIndexPath:indexPath];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        
        //下面这两个语句一定要添加,否则第一屏显示的collection view尺寸,以及里面的单元格位置会不正确
        cell.frame = tableView.bounds;
        [cell layoutIfNeeded];
        [cell reloadDataWithServiceList:(indexPath.row == 1)?[[self.moduleListDic objectForKey:@"base"] copy]:[[self.moduleListDic objectForKey:@"other"] copy]];
        cell.isShowTitleView = (indexPath.row == 1)?NO:YES;
        
        NTWeakself;
        [cell setNewOfficeServiceWasSelect:^(NTSubscribeModel *subscribModel, NSInteger index, NTNewOfficeServiceCell *unReadCell) {
            NTStrongself;
            [strongself configServiceWasSelect:unReadCell selectIndex:index selectModel:subscribModel];
        }];
        return cell;

遇到的问题。

  1. 刷新tableView时。使用setter方法中刷新collctionView的高度时,UITableViewCell高度不实时更新。

解释: 刚开始是collectionView中赋值时,使用的是直接赋值属性,也就是‘cell.arr = [arr copy]’, 在collection中使用setArr中来赋值,并且刷新collection。本来一行可以显示四个,当赋值四个item的时候,collectionView的contentSize高度会变成两行的高度。导致下一行不显示数据,就是撑过了。
查了一下代码,使用方法赋值后再刷新,就不会出现这个问题。

- (void)reloadDataWithServiceList:(NSArray *)servicetArr {
    if(servicetArr){
        _serviceListArr = servicetArr;
        [self.collectionView reloadData];
      
        //计算collectionView的contentSize的高度,再从新更新collectView的高度约束
        CGFloat height = self.collectionView.collectionViewLayout.collectionViewContentSize.height;
        self.collectionViewConstraint.constant = height;
        [self.collectionView.collectionViewLayout invalidateLayout];
    }
}
  1. 解决1问题后,首次刷新时,UICollectionViewCell的宽高度设置来撑起CollectView高度的预期值不一样。造成有一个动画显示。

解决方法:在tableViewCell中给UICollectionViewCell赋值时,在前面添加下面两行代码就OK,提前刷新一下tableViewCell.

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

推荐阅读更多精彩内容