UICollectionView inside CustomTableCell

2019-08-20 09:34发布

问题:

I have some problem when trying to implement UICollectionView with custom cell inside custom cell in tableView. I have custom table view cell which works fine, showing my label as I want.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath {
    TemperatureTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath: indexPath];
    Node *node = [[Node alloc] init];
    if(_nodes != nil){
        node = [_nodes objectAtIndex:indexPath.row];
        if(_tempSensorsDictionary.count > 0){
            NSArray *allSensors = [_tempSensorsDictionary objectForKey:node.number];
            TemperatureSensor *ts = allSensors[0];
            if(node.name != nil && ![node.name  isEqual: @""]){
                cell.unitNameLabel.text = node.name;
            } else {
                cell.unitNameLabel.text = node.number;
            }
            cell.collection = [_tempSensorsDictionary objectForKey:node.number];
        }
    }
    return cell;
}

I have set up CollectionView background to gray colour and I can see this "box". So I guess that CollectionView is initialised properly in my TemperatureTaleViewCell class where I putted:

@implementation TemperatureTableViewCell
-(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {

    if (!(self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) return nil;

    UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
    flowLayout.sectionInset = UIEdgeInsetsMake(10, 10, 10, 10);
    [flowLayout setItemSize:CGSizeMake(50, 50)];
    [flowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
    self.collectionView = [[CollectionView alloc] initWithFrame: CGRectZero collectionViewLayout:flowLayout];
    [self.collectionView registerClass:[TemperatureItemCollectionViewCell class] forCellWithReuseIdentifier:@"TemperatureItemCollectionCell"];
    self.collectionView.showsHorizontalScrollIndicator = NO;
    self.collectionView.dataSource = self;
    self.collectionView.delegate = self;

    [self.collectionView reloadData];
    [self.contentView addSubview:self.collectionView];
    return self;
}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    return 2;
}

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {

    TemperatureItemCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"TemperatureItemCollectionCell" forIndexPath:indexPath];
    cell.tempValTempCollViewCell.text = @"21oC";
    cell.backgroundColor = [UIColor redColor];

    return cell;

}
@end

But then my table view looks like this:

What is wrong in my code and where is wrong direction?

回答1:

Need to reload collection view data inside tableview cellForRowAtIndexPath method.

-(void)tableView:(UITableView *)tableView willDisplayCell:(CategoryCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    [cell setCollectionViewDelegate:self indexPath:indexPath];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath {
    TemperatureTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath: indexPath];
    Node *node = [[Node alloc] init];
    if(_nodes != nil){
        node = [_nodes objectAtIndex:indexPath.row];
        if(_tempSensorsDictionary.count > 0){
            NSArray *allSensors = [_tempSensorsDictionary objectForKey:node.number];
            TemperatureSensor *ts = allSensors[0];
            if(node.name != nil && ![node.name  isEqual: @""]){
                cell.unitNameLabel.text = node.name;
            } else {
                cell.unitNameLabel.text = node.number;
            }
            cell.collection = [_tempSensorsDictionary objectForKey:node.number];

            //Reload collection view data
            [cell.collectionView reloadData];
        }
    }
    return cell;
}

Use awakeFromNib method insted of table view initWithStyle method.

- (void)awakeFromNib
{
    [super awakeFromNib];
    UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
    flowLayout.sectionInset = UIEdgeInsetsMake(10, 10, 10, 10);
    [flowLayout setItemSize:CGSizeMake(50, 50)];
    [flowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
    self.collectionView = [[CollectionView alloc] initWithFrame: CGRectZero collectionViewLayout:flowLayout];
    [self.collectionView registerClass:[TemperatureItemCollectionViewCell class] forCellWithReuseIdentifier:@"TemperatureItemCollectionCell"];
    self.collectionView.showsHorizontalScrollIndicator = NO;
    self.collectionView.dataSource = self;
    self.collectionView.delegate = self;

    [self.contentView addSubview:self.collectionView];
}

Set delegate of collection view inside TemperatureTaleViewCell class

- (void)setCollectionViewDelegate:(id)dataSourceDelegate indexPath:(NSIndexPath *)indexPath
{
    self.collectionView.delegate = dataSourceDelegate;
}


回答2:

As I can see, you designed your TemperatureTaleViewCell via XIB/storyboard, and you create the cell via

[tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath: indexPath];

It's ok so far, but you're setting your collectionView's delegate and dataSource inside initWithStyle, which will not be called in this case. So your collection view's delegate and datasource methods will not be called.