美文网首页iOS开发
iOS UITableViewCell中包含UICollecti

iOS UITableViewCell中包含UICollecti

作者: 淘码小工 | 来源:发表于2018-06-03 15:53 被阅读1841次

    最近公司需要修改主界面,把以前所有服务类型都统一类型显示改为分模块化显示。也就造成以前用一个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];
    

    相关文章

      网友评论

        本文标题:iOS UITableViewCell中包含UICollecti

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