展开表格视图单元格消失

我有一个通过setExpanded:方法调用来改变高度的细胞。

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

问题是细胞消失,随机重新出现。 我怀疑这是索引工作的方式。

如果我打电话reloadData或beginUpdates / endUpdates细胞工作正常,但我失去了animation。

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

编辑:更新,包括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 } 

编辑2:我做了一个Quicktimevideo,了解正在发生的事情并提取屏幕截图。

我试图做的是扩大一个单元格,而不是replace,插入或删除单元格。 每个单元格都有一个或多个子视图。 单元格的高度根据是否“扩展”而改变。 内容视图添加了子视图,它的clipToBounds属性为YES。 当单元格随着单元格框架(包括背景视图和选定的背景视图)展开或折叠高度值发生变化时。 我在扩展之前,之中和之后都logging了所有的帧值,它们都与它们的状态和位置一致。

切分表视图设计

细胞挖掘

细胞扩大

细胞消失

细胞收缩

细胞再次可见

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

comaprison ios 4到ios 5

我没有看到模拟器中iOS 5.0和4.3.2之间的行为差​​异,或者手机上的5.0差异 – 单元格以相同的方式消失。 (我会在4.2.1旧iPod touch上进行testing,但Xcode 4不能。Grr ..)看起来有一个简单的解决方法,但是:如果你同时做了reloadRowsAtIndexPaths:withRowAnimation:展开/折叠你的单元格和那么在reloadData调用之后,它就会保留animation。

这是一个小的演示项目。 很难说真正的问题是什么 – 这只是UIKit如何进行单元animation的一个奇怪的副作用。 如果你inheritance[UITableViewCell setAlpha:],你可以看到表格视图将单元格的alpha设置为0,并将其留在那里。 奇怪的。

编辑:那很奇怪。 它没有工作一点点(正在做旧的行为,细胞消失),但现在它又是正确的。 也许我运行了错误的版本。 无论如何,让我知道这是否适合你。

我遇到过同样的问题。 我确认在重新加载该行时不使用animation可以正常工作。

但事实certificate,这个问题是由于返回一个caching的UITableViewCell在cellForRowAtIndexPath实际上是一个新的需要。

reloadRowsAtIndexPaths的文档:withRowAnimation:说:“重新加载一个行导致表视图要求其数据源为该行的新单元格”。

您的cellForRowAtIndexPath方法正在返回本地caching的单元格。 返回一个全新的单元格固定在我的情况下的问题,没有解决方法需要…

@Javy,

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

  1. 如果需要换行来显示文本而不滚动,或者
  2. 如果新行被删除,则会崩溃

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

我find了解决scheme,对我来说效果很好。

解决scheme:只要尝试用UITableViewRowAnimationNonereplaceanimationtypesUITableViewRowAnimationNone时重新加载特定的单元格。

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

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

希望它会帮助你。

对我来说,好像单元格没有正确重绘。

你有没有尝试类似的东西:

 [cell.backgroundView setNeedsDisplay] 

animation完成后,您可以尝试重新加载表格视图吗? 此刻如果你的animation被激发,然后你调用[tableView reloadData]animation将不会完成,所以框架等可能会不同步

你可以改变你设置的扩展方法来取得一个标志以及一个animation完成块,它可以包含重载代码

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

在:

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

你必须返回一个新的单元格。 如果你不需要创build一个新的单元,你只需要:

 [tableView beginUpdates]; [tableView endUpdates]; 

没有必要调用reloadRowsAtIndexPaths

好的…

在你之前

 previousIndexPath_ = indexPath; 

在你做完所有的高度扩展/收缩之后, 你需要做类似的事情

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

这意味着你的cellArray需要

 NSMutableArray* cellArray;