展开表格视图单元格消失
我有一个通过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上正常工作,如下所示:
我没有看到模拟器中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
),它们是:
- 如果需要换行来显示文本而不滚动,或者
- 如果新行被删除,则会崩溃
所以我发现了同样的问题。 在iOS 5.x中,当我开始input文本时,它突然变得不可见。 但在iOS 4.x中一切正常。
我find了解决scheme,对我来说效果很好。
解决scheme:只要尝试用UITableViewRowAnimationNone
replaceanimationtypesUITableViewRowAnimationNone
时重新加载特定的单元格。
一些额外的代码:在一瞬间重新加载这两个单元格:
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;