CustomTableCell 内的 UICollectionView

Posted

技术标签:

【中文标题】CustomTableCell 内的 UICollectionView【英文标题】:UICollectionView inside CustomTableCell 【发布时间】:2017-11-15 11:35:55 【问题描述】:

尝试在 tableView 中的自定义单元格内使用自定义单元格实现 UICollectionView 时遇到一些问题。 我有自定义表格视图单元格,可以正常工作,显示我想要的标签。

- (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;

我已将 CollectionView 背景设置为灰色,我可以看到这个“框”。所以我猜 CollectionView 在我放置的TemperatureTaleViewCell 类中正确初始化:

@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

但是我的表格视图看起来像这样:

我的代码有什么问题,方向错在哪里?

【问题讨论】:

【参考方案1】:

需要在tableview cellForRowAtIndexPath方法中重新加载collection view数据。

-(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;

使用 awakeFromNib 方法插入表格视图 initWithStyle 方法。

- (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];

TemperatureTaleViewCell 类中设置集合视图的委托

- (void)setCollectionViewDelegate:(id)dataSourceDelegate indexPath:(NSIndexPath *)indexPath

    self.collectionView.delegate = dataSourceDelegate;

【讨论】:

不幸的是没有帮助。重载在 CustomCell 初始化方法中完成。 此方法与 cmets 中提供的另一种方法一样有效。哪种方式更好,有什么区别?【参考方案2】:

正如我所见,您通过 XIB/storyboard 设计了 ​​TemperatureTaleViewCell,并通过

创建了单元格
[tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath: indexPath];

到目前为止一切正常,但是您在 initWithStyle 中设置了 collectionView 的委托和数据源,在这种情况下不会调用。所以你的集合视图的委托和数据源方法将不会被调用。

【讨论】:

请仔细阅读本文档并更新您的答案developer.apple.com/documentation/uikit/uitableview/… 如果您为指定的标识符注册了一个类并且必须创建一个新单元格,则此方法通过调用其 initWithStyle:reuseIdentifier: 方法来初始化该单元格。 所以我应该插入 if(cell == nil) cell = [[TemperatureTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"]; 后 TemperatureTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath: indexPath]; ?? @Micgal 进行初始化,你做对了。不要插入它。 @trungduc: 不,如果我不注册单元格的类(通过代码),而只是直接在 Xib/storyboard 上将单元格添加到我的 UITableView,方法 initWithStyle:reuseIdentifier 将不会被调用dequeueReusableCellWithIdentifier.

以上是关于CustomTableCell 内的 UICollectionView的主要内容,如果未能解决你的问题,请参考以下文章

collectionView:didSelectItemAtIndexPath:没有被调用

UIColllctionView 没有快速加载数组值

延迟加载 UICollectionViewCell 的自定义子视图

如何在协议扩展中设置委托

从 UIImageView 中删除对象

Swift 中的 UiSearchController 到 UiCollectionView