问题 UITableView:在空白部分添加部分页脚视图时崩溃


这是我第一次在这里问一个问题,但我不得不说这个网站在过去几个月对我来说是一个巨大的帮助(iphone-dev-wise),我感谢你。

但是,我找不到任何有关此问题的解决方案: 我有一个UITableView有2个部分,第一次启动应用程序时没有行。用户可以根据自己的意愿稍后填写这些部分(这里的内容不相关)。 UITableView在填充行时看起来很好,但是当没有行时看起来很丑陋(2个标题部分粘在一起而中间没有空格)。这就是为什么我想在没有行时添加一个漂亮的“无行”视图。

我使用了viewForFooterInSection:

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {

if(section == 0)
{
    if([firstSectionArray count] == 0)
        return 44;
    else 
        return 0;
}

return 0;

}

- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section{

    if(section == 0)
    {
        UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(200, 10, 50, 44)];
        label.backgroundColor = [UIColor clearColor];
        label.textColor = [UIColor colorWithWhite:0.6 alpha:1.0];
        label.textAlignment = UITextAlignmentCenter;
        label.lineBreakMode = UILineBreakModeWordWrap; 
        label.numberOfLines = 0;
        label.text = @"No row";
        return [label autorelease];
    }

    return nil;
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 2;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    if(section == 0)
    {
        return [firstSectionArray count];
    }
    return [secondSectionArray count];
}

这很好用:仅当第0部分中没有行时才会显示页脚视图。 但是当我进入编辑模式并删除第0部分中的最后一行时,我的应用程序崩溃:

断言失败 - [UIViewAnimation initWithView:indexPath:endRect:endAlpha:startFraction:endFraction:curve:animateFromCurrentPosition:shouldDeleteAfterAnimation:editing:]   由于未捕获的异常'NSInternalInconsistencyException'而终止应用程序,原因:'单元格动画停止分数必须大于开始分数'

当第0节中有多行时,不会发生这种情况。只有当只剩下一行时才会发生这种情况。

这是编辑模式的代码:

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    // If row is deleted, remove it from the list.
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        // Find the book at the deleted row, and remove from application delegate's array.

        if(indexPath.section == 0)
        { [firstSectionArray removeObjectAtIndex:indexPath.row]; }
        else 
        { [secondSectionArray removeObjectAtIndex:indexPath.row]; }

        // Animate the deletion from the table.
        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
                             withRowAnimation:UITableViewRowAnimationBottom];


        [tableView reloadData];

    }
}

有谁知道为什么会这样? 谢谢


6859
2017-12-12 15:12


起源



答案:


看起来它正在发生的是内部Apple的 UITableView 代码假设当您删除行时,视图的第一部分会变短。通过使节标题页脚突然变得更高以补偿最后一行,您似乎混淆了它。

您尝试的两个想法:

1。  尝试使可选的部分页脚比正在消失的表格单元格小一个或两个像素,这样动画代码就可以做一两个动画像素

2。 而不是删除表的唯一行,当没有“真正的”数据行时,让表仍然有 numberOfRowsInSection 返回1并制作一个假的“无数据”单元格而不是使用表格页脚来表示“无数据”情况。

在这种情况下,您必须接受Apple为您编写了一半程序,并且您必须遵守您的共同作者所做出的一些选择,无论您是否喜欢。


9
2017-12-12 16:52



你是我的英雄!使“无数据”单元格小2像素使它全部工作!非常感谢! (仅供参考,我已经考虑过第二个解决方案,但无法使其工作)我仍然有一个小问题:当第0节中没有行时,tableview的背景是白色的。当它被填充时我更喜欢它空单元格(见图像: yfrog.com/izuitableviewproblemp)。有提示吗?再次感谢大卫,你结识了我的一天! - nmondollot
那里没有好主意,也许值得一个单独的问题。 - David Maymudes
好的,那就是我做的。谢谢 - nmondollot


答案:


看起来它正在发生的是内部Apple的 UITableView 代码假设当您删除行时,视图的第一部分会变短。通过使节标题页脚突然变得更高以补偿最后一行,您似乎混淆了它。

您尝试的两个想法:

1。  尝试使可选的部分页脚比正在消失的表格单元格小一个或两个像素,这样动画代码就可以做一两个动画像素

2。 而不是删除表的唯一行,当没有“真正的”数据行时,让表仍然有 numberOfRowsInSection 返回1并制作一个假的“无数据”单元格而不是使用表格页脚来表示“无数据”情况。

在这种情况下,您必须接受Apple为您编写了一半程序,并且您必须遵守您的共同作者所做出的一些选择,无论您是否喜欢。


9
2017-12-12 16:52



你是我的英雄!使“无数据”单元格小2像素使它全部工作!非常感谢! (仅供参考,我已经考虑过第二个解决方案,但无法使其工作)我仍然有一个小问题:当第0节中没有行时,tableview的背景是白色的。当它被填充时我更喜欢它空单元格(见图像: yfrog.com/izuitableviewproblemp)。有提示吗?再次感谢大卫,你结识了我的一天! - nmondollot
那里没有好主意,也许值得一个单独的问题。 - David Maymudes
好的,那就是我做的。谢谢 - nmondollot


  • 制作空节
  • 在第一部分中使用此部分中的表头而不是页脚
- (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    if (section != OTHER_SECTION_INDEX) {
        return nil;
    }
    //your code here
}

- (CGFloat) tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    if (section != OTHER_SECTION_INDEX) {
        return 0;
    }
    //your code
}

5
2017-09-06 10:08



应该是什么“OTHER_SECTION_INDEX”? - LightningStryk
我的示例在header_view上使用footer_view进行更改 - 因此您需要在下面添加一个空部分以使用header_view。在这种情况下,OTHER_SECTION_INDEX == 0和header_view将在第1部分 - comonitos
对我不起作用。 - Carles Estevadeordal


没有必要同时打电话 deleteRowsAtIndexPaths:withAnimation: 和 reloadData 在tableView上。

你看到的问题是我在调用中看到的问题 deleteRowsAtIndexPaths:withAnimation:,因此,对你来说,它永远不会到达 reloadData 无论如何。

一个更简单的解决方案,必须创建新的单元格,管理它们,处理所有必须处理不同单元格的地方,是使用 reloadSections:withAnimation: 处理从0到1行或1到0行的节时。

即替换以下代码行:

        if(indexPath.section == 0)
        { [firstSectionArray removeObjectAtIndex:indexPath.row]; }
        else 
        { [secondSectionArray removeObjectAtIndex:indexPath.row]; }

        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
                         withRowAnimation:UITableViewRowAnimationBottom];

以下内容

        BOOL useReloadSection;
        if (indexPath.section == 0)
        {
            [firstSectionArray removeObjectAtIndex:indexPath.row];
            useReloadSection = 0 == firstSectionArray.count;
        }
        else 
        {
            [secondSectionArray removeObjectAtIndex:indexPath.row];
            useReloadSection = 0 == secondSectionArray.count;
        }

        if (useReloadSection)
            [tableView reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section]
                     withRowAnimation:UITableViewRowAnimationBottom];
        else
            [tableView deleteRowsAtIndexPaths:@[indexPath]
                             withRowAnimation:UITableViewRowAnimationBottom];

1
2017-12-12 08:16



谢谢!很棒的答案! - FunkyKat


我遇到了同样的崩溃,看起来像是一个 操作系统中的错误

我的具体用例适用于具有可折叠/可扩展部分的UITableView。我需要部分分隔符(这是我使用的部分页脚)但不是行分隔符(不能简单地使用单元格分隔符)。

我无法通过调整节页脚的高度来解决问题。但是切换到使用节头可以解决问题,不再发生错误/崩溃。

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    CGRect frame = (CGRect){0, 0, self.view.bounds.size.width, 1};
    UIView *view = [[UIView alloc] initWithFrame:frame];
    view.backgroundColor = [UIColor commentReplyBackground];

    return view;
}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    return 1.0f;
}

1
2018-04-22 15:36





对于那些仍然需要部分页脚的人,您也可以尝试将TableView样式更改为UITableViewStyleGrouped。这似乎绕过了这个问题。为了获得相同的视觉外观,您只需将所有其他页脚和标题设置为CGFLOAT_MIN即可。


0
2018-05-11 09:56