如何在 iOS 15 中正确加载/重新加载 UITableViewCells?

How does one properly load/reload UITableViewCells in iOS 15?

提问人:michaelthedeveloper 提问时间:5/19/2022 最后编辑:michaelthedeveloper 更新时间:5/20/2022 访问量:465

问:

大约一个星期以来,我一直在试图弄清楚表格视图单元格无法正确加载/重新加载的困境,这似乎只是在 iOS 15 中是一个问题。在低于 15 的 iOS 中运行相同的代码,单元格可以完美加载。当我在 iOS 15 中运行该应用程序时,单元格有时会重叠,有时间隔很远。我发现一些帖子建议在 iOS 15 中正确重新加载单元格的方法是使用 reconfigureRowsAtIndexPaths 而不是 reloadRowsAtIndexPaths,所以我尝试了一下,单元格加载的问题较少,但有时仍然间隔太远。

这是我的 cellForRowAt 的当前状态:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    VLMileageSummaryComparisonViewController *vc = [[VLMileageSummaryComparisonViewController alloc] init];
        
    UITableViewCell *cellComparison = [tableView dequeueReusableCellWithIdentifier:[NSString stringWithFormat:@"%ld_%ld", indexPath.section, indexPath.row]];
    if (cellComparison == nil) {
        cellComparison = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:[NSString stringWithFormat:@"%ld_%ld", indexPath.section, indexPath.row]];
    }

    [cellComparison.contentView vl_removeAllSubviews];
        
    [cellComparison.contentView addSubview:vc.view];
    vc.chartData = [self getChartDataForIndexPath:indexPath];
    [vc.view vl_PinEdgesToSuperview];
        
    cell = cellComparison;
    
    cell.backgroundColor = UIColor.backgroundInterfaceSecondary;
    cell.contentView.backgroundColor = UIColor.backgroundInterfaceSecondary;
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    
    return cell;
}

这是我的willDisplayCell,我在其中重新配置/重新加载单元格:

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    // Change the loading state of the chart data structure
    // When the loading state of the chart changes, reload that cell
    VLSummaryComparisonChartData *chartData = [self getChartDataForIndexPath:indexPath];
    if (chartData) {
        if (chartData.loadingState == LoadingStateUnknown) {
            if (self.reportComparisonDataSource) {
                chartData.loadingState = LoadingStateLoading;
                [self.reportComparisonDataSource getComparisonReportChartData:chartData force:true completion:^(SummaryComparisonData data, VLError * _Nullable error) {
                    if (error) {
                        chartData.loadingState = LoadingStateError;
                    } else {
                        chartData.data = data;
                        chartData.loadingState = LoadingStateLoaded;
                    }
                    dispatch_async(dispatch_get_main_queue(), ^{
                        if (@available(iOS 15.0, *)) {
                            [UIView performWithoutAnimation:^{
                                [tableView reconfigureRowsAtIndexPaths:@[indexPath]];
                            }];
                        } else {
                            [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
                        }
                    });
                }];
            }
        }
    }
}

下面是一个示例,说明单元格之间的间距有时如何关闭。我最近还在单元格的子视图中添加了相反的颜色,可以看到黄色视图的高度有时会关闭,这似乎与单元格之间的距离关闭有关:

enter image description here

下面是 VLMileageSummaryComparisonViewController 的笔尖,其中选择了黄色部分:

enter image description here

会很喜欢,非常感谢任何帮助。谢谢!!

iOS Swift Objective-C UITableView 自动布局

评论

0赞 vadian 5/19/2022
不相关,但对单个操作也没有影响。这些 API 用于多个同时插入/删除/移动操作。beginUpdates/endUpdatesperformBatchUpdates
0赞 michaelthedeveloper 5/20/2022
@vadian啊,谢谢你指出这一点。继续摆脱那些
1赞 DonMag 5/20/2022
看起来您每次调用时都会添加另一个视图——但这在 iOS 15 之前应该是有问题的。你看到这个,想的是“单元间距”——但更有可能的是,它是单元格的高度。使用和/或为您的单元格的子视图提供对比背景颜色,以便您(我们)可以看到框架的真实布局方式。VLMileageSummaryComparisonViewControllercellForRowAtDebug View Hierarchy
0赞 michaelthedeveloper 5/20/2022
@DonMag我更新了 cellForRowAt,以便在每次添加另一个 VLMileageSummaryComparisonViewController 之前删除单元格的 contentView 的子视图,从而摆脱了我看到的重叠问题!谢谢!我仍在处理间距问题,并按照您的建议添加了对比色并重新上传了图像。我可以看到,由于某种原因,黄色视图的高度没有被正确计算......
0赞 DonMag 5/22/2022
@michaelthedeveloper - 在不知道发生了什么的情况下很难分辨,但从 .黄色视图的高度是否取决于数据?reloadRowsAtIndexPathswillDisplayCell

答:

0赞 Sangeetha B 5/20/2022 #1

在 tableView:(UITableView *)tableView cellForRowAtIndexPath 中创建 VLMileageSummaryComparisonViewController 的实例可能是导致此问题的原因。 看起来您正在 tableView:(UITableView *)tableView willDidplayCell 方法中从服务器获取圆顶数据,这也可能是导致问题的原因。 尝试重构代码,重构可以帮助你解决问题。

评论

0赞 michaelthedeveloper 5/20/2022
我将VLMileageSummaryComparisonViewController的创建移到了它自己的函数中,并在willDisplayCell外部和viewDidAppear内部获取数据,结果相同