我通过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 . 当单元格展开或折叠时,高度值随单元格的框架一起变化(包括背景视图和选定的背景视图) . 我在扩展之前,期间和之后都记录了所有帧值,并且它们都与它们的状态和位置一致 .
请记住,这在iOS 4.3上正常工作,如下所示:
7 回答
我没有看到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并将其保留在那里 . 奇怪的 .
编辑:那太奇怪了 . 它没有起作用(正在做旧的行为,细胞消失了),但现在又恢复正常了 . 也许我的版本运行错误 . 无论如何,请告诉我这是否适合您 .
我遇到过同样的问题 . 我确认重新加载行时不使用动画可以正常工作 .
但事实证明,问题是由于在实际需要新的时候在cellForRowAtIndexPath中返回缓存的UITableViewCell引起的 .
reloadRowsAtIndexPaths:withRowAnimation的文档说:“重新加载一行会导致表视图向其数据源询问该行的新单元格 . ”
您的cellForRowAtIndexPath方法返回本地缓存的单元格 . 返回一个全新的单元格修复了我的问题,并且不需要解决方法......
@Javy,
谢谢你的提问 . 我正在开发具有类似行为的表:我的表视图单元格(
UITableViewCell
)中有文本视图(UITextView
),它们是:如果删除了新行,则
所以我发现了同样的问题 . 在iOS 5.x中,当我开始输入文本时,它突然变得不可见 . 但在iOS 4.x中一切正常 .
我找到了解决方案,对我来说效果很好 .
Solution: 重新加载特定单元格时,尝试用
UITableViewRowAnimationNone
替换动画类型UITableViewRowAnimationAutomatic
.一些额外的代码:在一瞬间重新加载两个单元格:
希望它会对你有所帮助 .
在我看来,单元格没有正确重绘 .
你尝试过这样的事情:
您可以尝试在动画完成后重新加载表格视图?如果您的动画被解雇,然后您调用
[tableView reloadData]
,动画将无法完成,因此帧等可能会失去同步你可以改变你的set expand方法来获取一个标志以及一个动画完成块,它可以包含重载代码
在:
你必须返回一个新的细胞 . 如果单元格不需要创建新单元格,则只需:
无需拨打
reloadRowsAtIndexPaths
.好的...
在你面前
并且在你完成所有扩展/收缩高度之后;你需要做点什么
这意味着你的cellArray需要