首页 文章

扩展表格视图单元格消失

提问于
浏览
17

我通过setExpanded:方法调用改变高度来扩展单元格 .

然后我调用reloadRowsAtIndexPaths:刷新单元格 .

问题是细胞消失并随机重新出现 . 我怀疑这与索引工作方式有关 .

如果我调用reloadData或beginUpdates / endUpdates,单元格按预期工作,但我丢失了动画 .

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    JVCell *cell = (JVCell*)[tableView cellForRowAtIndexPath:indexPath];
    JVCell *previousCell = nil;

    if( previousIndexPath_ != nil ) // set to nil in viewDidLoad
    {
        previousCell = (JVCell*)[tableView cellForRowAtIndexPath:previousIndexPath_];
    }


    // expand or collapse cell if it's the same one as last time
    if( previousCell != nil && [previousIndexPath_ compare:indexPath] == NSOrderedSame && [previousCell expandable] )
    {
        [previousCell setExpanded:![cell expanded]];
        NSArray *indexPathArray = [NSArray arrayWithObject:previousIndexPath_];
        [tableView reloadRowsAtIndexPaths:indexPathArray withRowAnimation:UITableViewRowAnimationAutomatic];
    }
    else
    {
        // collapse previous cell
        if( previousCell != nil && [previousCell expandable] )
        {
            if( [previousCell expanded] ) [previousCell setExpanded:NO];
            NSArray *indexPathArray = [NSArray arrayWithObject:previousIndexPath_];
            [tableView reloadRowsAtIndexPaths:indexPathArray withRowAnimation:UITableViewRowAnimationAutomatic];
        }

        // expand new cell
        if( [cell expandable] )
        {
            [cell setExpanded:YES];
            NSArray *indexPathArray = [NSArray arrayWithObject:indexPath];
            [tableView reloadRowsAtIndexPaths:indexPathArray withRowAnimation:UITableViewRowAnimationAutomatic];
        }
    }

    previousIndexPath_ = indexPath;

    // works as expected, but I lose the animations
    //[tableView reloadData];

    // works as expected, but I lose the animations
    //[tableView beginUpdates];
    //[tableView endUpdates];
}

EDIT: 已更新,包括cellForRowAtIndexPath和heightForRowAtIndexPath方法:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSUInteger section = [indexPath section];
    NSUInteger row = [indexPath row];
    JVCellSectionData *sectionData = [sections_ objectAtIndex:section]; // NSArray of SectionData objects
    NSArray *cellArray = [sectionData cells]; // NSArray of cells
    UITableViewCell *cell = [cellArray objectAtIndex:row];
    return cell;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSUInteger section = [indexPath section];
    NSUInteger row = [indexPath row];
    JVCellSectionData *sectionData = [sections_ objectAtIndex:section];
    NSArray *cellArray = [sectionData cells];
    JVCell *cell = [cellArray objectAtIndex:row];
    return [cell cellHeight]; // changed when selected with setExpanded: method
}

Edit 2: 我制作了Quicktime视频,了解正在发生的事情并提取屏幕截图 .

我正在尝试做的是扩展单元格,而不是替换,插入或删除单元格 . 每个单元格都有一个或多个子视图 . 细胞的高度根据它是否“扩展”而改变 . 内容视图添加了子视图,其clipToBounds属性为YES . 当单元格展开或折叠时,高度值随单元格的框架一起变化(包括背景视图和选定的背景视图) . 我在扩展之前,期间和之后都记录了所有帧值,并且它们都与它们的状态和位置一致 .

sectioned table view design

cell tapped

cell expanding

cell disappeared

cell retracts

cell visible again

请记住,这在iOS 4.3上正常工作,如下所示:

comaprison ios 4 to ios 5

7 回答

  • 0

    我没有看到iOS 5.0和4.3.2在模拟器中的行为有什么不同,或者在我的手机上看不到5.0 - 细胞在每个上都以相同的方式消失 . (我在我的旧款iPod touch上测试4.2.1,但Xcode 4不能测试.Grr ..)看起来有一个简单的解决方法:如果你同时执行reloadRowsAtIndexPaths:withRowAnimation:扩展/折叠你的细胞后然后reloadData调用之后,它似乎保留动画 .

    Here's这是一个小型的演示项目 . 它's hard to say what the actual problem was—it'只是UIKit如何进行细胞动画的一些奇怪的副作用 . 如果您继承[UITableViewCell setAlpha:],则可以看到表视图将单元格的alpha设置为0并将其保留在那里 . 奇怪的 .

    编辑:那太奇怪了 . 它没有起作用(正在做旧的行为,细胞消失了),但现在又恢复正常了 . 也许我的版本运行错误 . 无论如何,请告诉我这是否适合您 .

  • 5

    我遇到过同样的问题 . 我确认重新加载行时不使用动画可以正常工作 .

    但事实证明,问题是由于在实际需要新的时候在cellForRowAtIndexPath中返回缓存的UITableViewCell引起的 .

    reloadRowsAtIndexPaths:withRowAnimation的文档说:“重新加载一行会导致表视图向其数据源询问该行的新单元格 . ”

    您的cellForRowAtIndexPath方法返回本地缓存的单元格 . 返回一个全新的单元格修复了我的问题,并且不需要解决方法......

  • 0

    @Javy,

    谢谢你的提问 . 我正在开发具有类似行为的表:我的表视图单元格( UITableViewCell )中有文本视图( UITextView ),它们是:

    • 扩展如果需要换行来显示文本而不滚动,或者
      如果删除了新行,则
    • 会折叠

    所以我发现了同样的问题 . 在iOS 5.x中,当我开始输入文本时,它突然变得不可见 . 但在iOS 4.x中一切正常 .

    我找到了解决方案,对我来说效果很好 .

    Solution: 重新加载特定单元格时,尝试用 UITableViewRowAnimationNone 替换动画类型 UITableViewRowAnimationAutomatic .

    一些额外的代码:在一瞬间重新加载两个单元格:

    NSMutableArray *indexes = [NSMutableArray arrayWithCapacity:2];
        // collapse previous cell
        if( previousCell != nil && [previousCell expandable] )
        {
            if( [previousCell expanded] ) [previousCell setExpanded:NO];
            [indexes addObject:previousIndexPath_];
        }
    
        // expand new cell
        if( [cell expandable] )
        {
            [cell setExpanded:YES];
            [indexes addObject:indexPath];
        }
    
        [tableView reloadRowsAtIndexPaths:indexes withRowAnimation:UITableViewRowAnimationNone];
    

    希望它会对你有所帮助 .

  • 7

    在我看来,单元格没有正确重绘 .

    你尝试过这样的事情:

    [cell.backgroundView setNeedsDisplay]
    
  • 2

    您可以尝试在动画完成后重新加载表格视图?如果您的动画被解雇,然后您调用 [tableView reloadData] ,动画将无法完成,因此帧等可能会失去同步

    你可以改变你的set expand方法来获取一个标志以及一个动画完成块,它可以包含重载代码

    [cell setExpanded:YES completion:^
        //reload code
    }];
    
  • -1

    在:

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    

    你必须返回一个新的细胞 . 如果单元格不需要创建新单元格,则只需:

    [tableView beginUpdates];
    [tableView endUpdates];
    

    无需拨打 reloadRowsAtIndexPaths .

  • 0

    好的...

    在你面前

    previousIndexPath_ = indexPath;
    

    并且在你完成所有扩展/收缩高度之后;你需要做点什么

    [cellArray replaceObjectAtIndex:previousIndexPath_ withObject:previousCell];
    [cellArray replaceObjectAtIndex:indexPath withObject:cell];
    

    这意味着你的cellArray需要

    NSMutableArray* cellArray;
    

相关问题