iOS:不为 UICollectionView 中包含的 UITableView 调用 cellFowRow

Posted

技术标签:

【中文标题】iOS:不为 UICollectionView 中包含的 UITableView 调用 cellFowRow【英文标题】:iOS: cellFowRow not called for UITableView contained in UICollectionView 【发布时间】:2014-03-21 13:40:29 【问题描述】:

我的应用包含一个 UICollectionView,其中每个单元格都包含一个 UITableView。表格视图的行数方法被正确调用,但 cellForRow 方法从未被调用。以下是相关代码:

设置表格视图(在视图中加载):

[self.collectionView registerNib:[UINib nibWithNibName:@"OrganizationCollectionCell" bundle:nil] forCellWithReuseIdentifier:@"OrganizationCollectionCell"];


    tableViews = [[NSMutableArray alloc] initWithCapacity:recipOrgs.count];

    for (NSDictionary *orgDict in recipOrgs) 

        int index = [recipOrgs indexOfObject:orgDict];


        OrganizationTableView *tableView = [[OrganizationTableView alloc] initWithFrame:collectionView.frame];

        tableView.index=index;
        tableView.parentCon=self;
        tableView.dataSource=tableView;
        tableView.delegate=tableView;

        [tableViews addObject:tableView];

    

CollectionView 的 cellForItem:

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
    NSLog(@"cellForItem CollectionView");
    OrganizationCollectionCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"OrganizationCollectionCell" forIndexPath:indexPath];

    if (cell==nil) 
        NSArray *objects = [[NSBundle mainBundle] loadNibNamed:@"OrganizationCollectionCell" owner:self options:nil];
        cell = [objects objectAtIndex:0];
    

    OrganizationTableView *tv = [tableViews objectAtIndex:indexPath.row];
    if (tv.orgAlerts==nil) 
        [tv getAlerts];
    

    cell.tableView=tv;
    cell.tableView.frame=collectionView.frame;
    NSLog(@"%f %f",cell.tableView.frame.size.height,cell.tableView.frame.size.height);

    return cell;


“getAlerts”方法:

-(void)getAlerts

    orgAlerts = [[NSArray alloc] init];
    NSString *orgID = [[parentCon.recipOrgs objectAtIndex:index] objectForKey:@"id"];

    [[EDAPIStore sharedStore] getAlertsForOrganizationWithID:orgID WithCompletion:^(NSArray *alerts, NSError *error) 

        if (alerts) 

             orgAlerts = alerts;
            [self reloadData];
        else
            NSLog(@"%@",error.localizedDescription);
        

    ];

OrganizationTableView 的 numberOfRowsMethod:

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    NSLog(@"number of rows");
    NSLog(@"orgAlerts.count: %d",orgAlerts.count);
    if (orgAlerts.count==0) 

        return 1;
    else
        return orgAlerts.count;
    

我已验证 numberOfRows 返回正确的数字(大约 30),但从未调用 cellForRow 方法。集合单元格和表格视图单元格都在自己的 xib 中定义。

【问题讨论】:

也许你应该把这个发到code review。也许吧。 CodeReview 用于审查工作代码,而不是用于调试代码。 @YuchenZhong 有点相关:meta.stackexchange.com/questions/64068/… 即使是在Code Review 上也不会被允许... @YuchenZhong 请阅读CR's on-topic page 并在建议迁移之前实际验证问题是否会在目标站点上成为主题。 CR 不是调试服务,也不是 SO 不想调试的任何东西的垃圾场。这个问题有一个特定的编程问题,并且是 Stack Overflow 的主题。赞成。 我注意到您将 tableView 框架设置为 collectionView 框架,这似乎本质上是有问题的。在这种情况下不应该设置为 cell.bounds 吗?由于 cellForRow 只会为可见行调用,如果框架被冲洗并且没有可见行,则永远不会调用 cellForRows。 【参考方案1】:

不要在视图控制器的viewDidLoad 中设置表视图的dataSourcedelegate,而是在collectionView:cellForItemAtIndexPath: 方法中获取对UICollectionViewCellUITableView 的引用,并设置其@ 987654327@ 和 delegate 那里。对于任何带有委托的视图,这似乎是在 ios 中执行此操作的方式,并且放在 UITableViewCellUICollectionViewCell 中。因此,如果您发现自己使用UITableViewController 构建表单,而UITableView 内部有UITextFields,请在cellForRowAtIndexPath: 方法中设置文本字段委托。

我还要补充一点,在您的集合视图单元格中保持对所有UITableViews 的强引用在内存上可能非常昂贵。您的集合视图可能正在重用“原型”集合视图单元,而不是已自定义为在内部包含 UITableView。然后,在您的视图控制器中,保留一个二维的NSArray 作为集合视图的数据源。第一个维度是您的集合视图,第二个维度是每个表格视图的数据源。

【讨论】:

以上是关于iOS:不为 UICollectionView 中包含的 UITableView 调用 cellFowRow的主要内容,如果未能解决你的问题,请参考以下文章

UIcollectionView在ios 7中重新加载重叠

如何在 iOS 中动态更改 UICollectionView 单元格高度

iOS14 中 UICollectionview 的潜在错误

iOS中UICollectionView自适应

iOS 7.1 在 UIPopover 中嵌套 UICollectionView

UICollectionView 部分标题崩溃 iOS 8