cell嵌套collectionView

作者: 大墙66370 | 来源:发表于2016-07-21 18:29 被阅读5468次

    买来叶孤城的电子书看到书中有这么一个场景,每个cell上有不定个按钮或者View.怎嘛写好呢?for循环布局?一个cell上如果很多view呢?......
    把collectionView放在cell里其实挺好的,还有每个每个cell的点击事件直接可以写在 代理方法中..

    先简要说明一下思路
    1创建一个tableView加到控制器上 遵守协议实现代理方法...不拉不拉那一堆事...... 返回一个 固定高度(因为这个时候不知道那个每个cell的高度是多少合适,先固定 以后变)

    2重写tableViewCell 在cell中创建 collectionView并且加到cell中 注意 因为collectionView的高度是根据cell来说的,这个时候还不知道cell有多少先随便给一个定值 (后期再改)collectionView用masonry写约束 是 top left right height

    问题
    怎么得到collectionView的内容视图的的高度呢? 知道collectionView的内容视图的的高度之后改了collectionView的高度,怎嘛改变 tableViewCell的高度呢?

    一切尽在代码中

    控制器.h

    //
    //  ViewController.h
    //  tableViewCell中加载collectionView
    //
    //  Created by 3D on 16/7/20.
    //  Copyright © 2016年 3D. All rights reserved.
    //
    
    #import <UIKit/UIKit.h>
    
    @interface ViewController : UIViewController
    @end
    

    控制器.m

     //
     //  ViewController.m
     //  tableViewCell中加载collectionView
     //
     //  Created by 3D on 16/7/20.
     //  Copyright © 2016年 3D. All rights reserved.
     //
    
     #import "ViewController.h"
     #import "testTableViewCell.h"
    @interface ViewController ()<UITableViewDataSource,UITableViewDelegate,testTableViewCellDelegate>
    @property(nonatomic,strong)UITableView *tableView;
    @property(nonatomic,strong)testTableViewCell *toolCell;
    @property(nonatomic,strong)NSArray *dataArr;
    @property(nonatomic,strong)NSMutableDictionary *dicH;
    
    
    @property(nonatomic,strong)UILabel *numLabel;
    @property(nonatomic,strong)CADisplayLink *displayLink;
    @property(nonatomic,assign)NSTimeInterval lastTime;
    @property(nonatomic,assign)NSInteger   count;
    @end
    @implementation ViewController
    
     -(NSArray *)dataArr{
    if (!_dataArr) {
        _dataArr = @[
                    @[@"g"],
                    @[@"g",@"b"],
                    @[@"g",@"b",@"a"],
                    @[@"g",@"b",@"c",@"e"],
                    @[@"g",@"b",@"c",@"e",@"a"],
                    @[@"g",@"b",@"c",@"e",@"b",@"c"],
                    @[@"g",@"b",@"c",@"e",@"b",@"c",@"a"],
                    @[@"g",@"b",@"c",@"e",@"b",@"c",@"b",@"c"],
                    @[@"g",@"b",@"c",@"e",@"b",@"c",@"e",@"d",@"g"],
                    @[@"g",@"b",@"c",@"e",@"b",@"c",@"e",@"d",@"a",@"c"],
                    @[@"g",@"b",@"c",@"e",@"b",@"c",@"e",@"d",@"a",@"c",@"e"],
                    @[@"g",@"b",@"c",@"e",@"b",@"c",@"e",@"d",@"a",@"c",@"a",@"b"],
                    @[@"g",@"b",@"c",@"e",@"b",@"c",@"e",@"d",@"a",@"c",@"a",@"b",@"a"],
                    @[@"g",@"b",@"c",@"e",@"b",@"c",@"e",@"d",@"a",@"c",@"a",@"b",@"a",@"14"],
                    @[@"g",@"b",@"c",@"e",@"b",@"c",@"e",@"d",@"a",@"c",@"a",@"b",@"a",@"14",@"15"],
                    @[@"g",@"b",@"c",@"e",@"b",@"c",@"e",@"d",@"a",@"c",@"a",@"b",@"a",@"14",@"15",@"16"],
                    @[@"g",@"b",@"c",@"e",@"b",@"c",@"e",@"d",@"a",@"c",@"a",@"b",@"a",@"14",@"15",@"16",@"17"],
                    @[@"g",@"b",@"c",@"e",@"b",@"c",@"e",@"d",@"a",@"c",@"a",@"b",@"a",@"14",@"15",@"16",@"17",@"18"],
                    @[@"g",@"b",@"c",@"e",@"b",@"c",@"e",@"d",@"a",@"c",@"a",@"b",@"a",@"14",@"15",@"16",@"17",@"18",@"19"],
                    @[@"g",@"b",@"c",@"e",@"b",@"c",@"e",@"d",@"a",@"c",@"a",@"b",@"a",@"14",@"15",@"16",@"17",@"18",@"19",@"20"],
                    @[@"g",@"b",@"c",@"e",@"b",@"c",@"e",@"d",@"a",@"c",@"a",@"b",@"a",@"14",@"15",@"16",@"17",@"18",@"19",@"20",@"21"],
                    @[@"g",@"b",@"c",@"e",@"b",@"c",@"e",@"d",@"a",@"c",@"a",@"b",@"a",@"14",@"15",@"16",@"17",@"18",@"19",@"20",@"21",@"22"],
                    @[@"g",@"b",@"c",@"e",@"b",@"c",@"e",@"d",@"a",@"c",@"a",@"b",@"a",@"14",@"15",@"16",@"17",@"18",@"19",@"20",@"21",@"22",@"23"],
                    @[@"g",@"b",@"c",@"e",@"b",@"c",@"e",@"d",@"a",@"c",@"a",@"b",@"a",@"14",@"15",@"16",@"17",@"18",@"19",@"20",@"21",@"22",@"23",@"24"]
                    
                    ];
        
    }
    return _dataArr;
    }
    
     -(UITableView *)tableView{
    if (!_tableView) {
        _tableView = [[UITableView alloc]initWithFrame:self.view.bounds style:UITableViewStylePlain];
        _tableView.delegate = self;
        _tableView.dataSource = self;
        [_tableView registerClass:[testTableViewCell class] forCellReuseIdentifier:@"cell"];
    }
    return _tableView;
    }
    
     - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return self.dataArr.count;
    }
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    testTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
    cell.lable.text = [NSString stringWithFormat:@"%ld",indexPath.row];
    
    cell.deleget = self;
    cell.indexPath = indexPath;
    cell.dataArr = self.dataArr[indexPath.row];
    return cell;
    }
    
    
     -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    if (self.dicH[indexPath]) {
        NSNumber *num = self.dicH[indexPath];
        return [num floatValue];
    }else{
    return 80;
    }
    }
    
     -(void)uodataTableViewCellHight:(testTableViewCell *)cell andHight:(CGFloat)hight andIndexPath:(NSIndexPath *)indexPath{
    
    if (![self.dicH[indexPath] isEqualToNumber: @(hight)]) {
        self.dicH[indexPath] = @(hight);
        NSLog(@"indexPath.row = %ld",indexPath.row);
        NSLog(@"高度 = %lf",[@(hight) floatValue]);
        [self.tableView reloadData];
    }
    }
    
     #pragma mark 下面是检测流畅度
     - (void)viewDidLoad {
     [super viewDidLoad];
    [self.view addSubview:self.tableView];
    [self setupUI];
    _displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayAction:)];
    [_displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
    
       }
    
     -(void)dealloc
    {
    [_displayLink removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
    _displayLink = nil;
    }
    
    -(void)setupUI
    {
    _numLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 50, 20)];
    _numLabel.text = @"60";
    _numLabel.textColor = [UIColor greenColor];
    _numLabel.backgroundColor = [UIColor blackColor];
    [self.view addSubview:_numLabel];
    }
    
    -(void)displayAction:(id)sender
    {
    if (_lastTime == 0) {
        _lastTime = _displayLink.timestamp;
        return;
    }
    
    _count++;
    NSTimeInterval delta = _displayLink.timestamp - _lastTime;
    if (delta < 1) return;
    _lastTime = _displayLink.timestamp;
    float fps = _count / delta;
    _count = 0;
    
    NSString *text = [[NSString alloc] initWithString:[NSString stringWithFormat:@"%d FPS", (int)round(fps)]];
    _numLabel.text = text;
    }
    - (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
    }
    
    #pragma mark 保存cell高度
    - (NSMutableDictionary *)dicH {
    if(_dicH == nil) {
        _dicH = [[NSMutableDictionary alloc] init];
    }
    return _dicH;
    }
    @end
    

    testTableViewCell.h

    //
    //  testTableViewCell.h
    //  tableViewCell中加载collectionView
    //
    //  Created by 3D on 16/7/20.
    //  Copyright © 2016年 3D. All rights reserved.
    //
    
    #import <UIKit/UIKit.h>
    
    @class testTableViewCell;
    @protocol testTableViewCellDelegate <NSObject>
    
    -(void)uodataTableViewCellHight:(testTableViewCell*)cell andHight:(CGFloat)hight andIndexPath:(NSIndexPath *)indexPath;
    @end
    
    @interface testTableViewCell : UITableViewCell
    @property(nonatomic,strong)NSIndexPath *indexPath;
    @property(nonatomic,strong)NSArray *dataArr;
    @property(nonatomic,weak) id<testTableViewCellDelegate>deleget;
    @property(nonatomic,strong)UILabel *lable;
    @end
    

    testTableViewCell.m

    //
    //  testTableViewCell.m
    //  tableViewCell中加载collectionView
    // 
    //  Created by 3D on 16/7/20.
    //  Copyright © 2016年 3D. All rights reserved.
    //
    
    #import "testTableViewCell.h"
    #import "textCollectionViewCell.h"
    #import <Masonry.h>
    
    @interface testTableViewCell ()<UICollectionViewDataSource,UICollectionViewDelegate,UICollectionViewDelegateFlowLayout>
    
    @property(nonatomic,strong)UICollectionView *collectionView;
    @property(nonatomic,assign)CGFloat hightED;
    @end
    
    @implementation testTableViewCell
    -(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
    
    self.hightED = 0.0;
    
    if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
    
        self.lable = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 50, 50)];
        [self.contentView addSubview:self.lable];
        
        [self.contentView addSubview:self.collectionView];
        [self.collectionView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.top.mas_equalTo(0);
            make.left.mas_equalTo(50);
            make.right.mas_equalTo(-50);
            make.height.mas_equalTo(50);//先随定一个
        }];
    }
    return self;
    }
    
    -(UICollectionView *)collectionView{
    if (!_collectionView) {
        UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc]init];
        layout.scrollDirection =     UICollectionViewScrollDirectionVertical;
        _collectionView = [[UICollectionView alloc]initWithFrame:CGRectZero collectionViewLayout:layout];
        _collectionView.delegate = self;
        _collectionView.dataSource = self;
    
        [_collectionView registerClass:[textCollectionViewCell class] forCellWithReuseIdentifier:@"123"];
        _collectionView.backgroundColor = [UIColor yellowColor];
        
    }
    return _collectionView;
    }
    
    -(void)setDataArr:(NSArray *)dataArr{
    [self.collectionView reloadData]; //重新换数据源的时候 记得重回用的cell上的colletionView重新加载数据
    self.hightED = 0; //当重新换数据源的时候 初始化自己的高度. (如果不写 就有一种意外比如 比如一个cell被重用,开始这个cell的collectionView的cell 和重用之后是一样的  self.hightED != hight  重用之前 和重用之后的内容高度 很定是一样的啊 那么他的高度是不用跟新 但是更新tableViewCell的高度的 代理方法还是 要走吧)
    _dataArr = dataArr;
    }
    
    
     - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
    if (self.dataArr.count == 0) {
        return 1;
    }else{
        return self.dataArr.count;
    }
    }
    
    - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
    textCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"123" forIndexPath: indexPath];
    cell.backgroundColor = [UIColor blackColor];
    
    [self updateCollectionViewHight:self.collectionView.collectionViewLayout.collectionViewContentSize.height];
    
    return cell;
    }
    
    - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
    
    return CGSizeMake(40, 60);
    }
    - (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section{
    return UIEdgeInsetsMake(10, 10, 10, 10);
     }
    - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section{
    
    return 10;
    }
    - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section{
    
    return 10;
    }
    
    
     -(void)updateCollectionViewHight:(CGFloat)hight{
    
    NSLog(@"+%@",self);
    NSLog(@"++ %f",self.hightED);
    NSLog(@"+++ %f",hight);
    
    if (self.hightED != hight) { //这个判断起到两个作用 第一 以为这个方法被调用多次这样写 保证 每个cell里面调用一次,切只调用一次  第二是当cell被重用从用的cell上的collectionView内容高度不一样的时候重新 更新跟新高度
        self.hightED = hight;
        
        NSLog(@"+++++%ld",self.indexPath.row);
        [self.collectionView mas_updateConstraints:^(MASConstraintMaker *make) {
            make.height.mas_equalTo(hight);
        }];
        
        if (_deleget && [_deleget respondsToSelector:@selector(uodataTableViewCellHight:andHight:andIndexPath:)]) {
            [self.deleget uodataTableViewCellHight:self andHight:hight andIndexPath:self.indexPath];
        }
    }
    }
    
    - (void)awakeFromNib {
    // Initialization code
    }
    
    - (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];
    
    // Configure the view for the selected state
    }
    @end
    

    textCollectionViewCell.h

     //
     //  textCollectionViewCell.h
     //  tableViewCell中加载collectionView
     //
     //  Created by 3D on 16/7/20.
     //  Copyright © 2016年 3D. All rights reserved.
    //
    
    #import <UIKit/UIKit.h>
    
    @interface textCollectionViewCell : UICollectionViewCell
    @property(nonatomic,strong)NSString *imageName;
    @end
    

    textCollectionViewCell.m

    //
    //  textCollectionViewCell.m
    //  tableViewCell中加载collectionView
    //
    //  Created by 3D on 16/7/20.
    //  Copyright © 2016年 3D. All rights reserved.
    //
    
    #import "textCollectionViewCell.h"
    
    @interface textCollectionViewCell ()
    @property(nonatomic,strong)UIImageView *imageView;
    
    @end
    
    @implementation textCollectionViewCell
    -(instancetype)initWithFrame:(CGRect)fram{
    if (self = [super initWithFrame:fram]) {
        self.imageView  = [[UIImageView alloc]init];
        self.backgroundView = self.imageView;
        self.imageView.image = [UIImage imageNamed:@"a"];
    }
    return self;
    }
    
    -(void)setImageName:(NSString *)imageName{
    _imageName  = imageName;
    self.imageView.image = [UIImage imageNamed:_imageName];
    }
     @end
    

    在最后我有一个疑问,为啥模拟器卡的一比,而真机比较流畅.
    哪里写的不好请指出😊互相学习

    6808D59A-6AB8-4190-910F-1D878DE26710.png

    运行效果图

    2016-07-21 18_15_47.gif

    相关文章

      网友评论

      • 幻海灬情仇:大神,有demo吗?求教
        大墙66370:@幻海灬情仇 就是cell中的collectionview是瀑布流对吗?
        幻海灬情仇:@大墙66370 我需要写成瀑布流,怎么改
        大墙66370:@幻海灬情仇 你可以私信讨论我现在不太忙
      • 峰子1994:你好在不遇到一个问题就是在tableview中嵌套collectionview怎么会出现数据错乱呀,collectionview里面显示的内容有问题呀
      • 后知后觉___:非常感谢🙏
      • 哈哈大笑呼呼呼呼:你好能把叶孤城电子书的链接分享下没有找到 谢谢
        大墙66370:@M了个K 网站都关闭了。
      • Alexander:大神, 给collecton cell赋值的时候, 它只显示了前面三个数据, 共有8组, 每组有三个数据, 但是每组显示的数据都是一样的. 数组中有24个数据.麻烦大神指导一下
        Alexander:@大墙66370 怪我问了一个比较低级的问题 :joy:
        大墙66370:@阿叔Alex 我内心是想帮你解决bug的,但是代码是你自己写的,你的代码你最了解,我写一个例子,只是一个例子啊,每个人看了例子会根据自己的需求写出不同得代码。很具体的bug在没有代码的情况下,真的很难回答不好意思。
      • d920e665d3d1:怎么给collecton cell赋值啊
      • Charles___:建议懒加载视图的话 可以使用weak属性,而不是strong属性,用strong是没有什么必要的。
      • 小白我们走吧:如果我要点击collection view的cell跳转页面,要怎么写呢
        大墙66370:@万军丛中一坨屎 你可以粘贴复制自己看看啊。还有你的问题我咋回答啊。:sweat:
        d920e665d3d1: @一只孤独的iOS 同问,这个具体怎么操作啊
        Charles___:@花無缺 需要两层代理回调。
      • 24125cd48243:你好,有 demo 吗?
        Charles___:@孙湖滨 可以去看下这个链接https://github.com/Charlesyaoxin
        大墙66370:@孙湖滨 粘贴复制就行。
      • xxttw:书 写的怎么样
        大墙66370:@Unc1eWang 还没看完,不评论
      • 左左4143:你好 电子书从哪买的能否告知?
        480a4933fcba:@Elephan_z 叶孤城微博

      本文标题:cell嵌套collectionView

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