UITableViewCell展开和折叠

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { //case 1 //The user is selecting the cell which is currently expanded //we want to minimize it back if(selectedIndex == indexPath.row) { selectedIndex = -1; [tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; return; } //case 2 //First we check if a cell is already expanded. //If it is we want to minimize make sure it is reloaded to minimize it back if(selectedIndex >= 0) { NSIndexPath *previousPath = [NSIndexPath indexPathForRow:selectedIndex inSection:0]; selectedIndex = indexPath.row; [tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:previousPath] withRowAnimation:UITableViewRowAnimationFade]; } //case 3 //Finally set the selected index to the new selection and reload it to expand selectedIndex = indexPath.row; [tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; } 

请注意案例1和案例2是如何相关的折叠已展开的行,其中案例3是关于展开未展开的行。

expand和collapse都使用reloadRowsAtIndexPaths函数的相同function。

对我来说问题是,一个切换按钮,当它被展开时,再次运行该function将崩溃,当它崩溃时,它会扩展?

当你调用reloadRowsAtIndexPaths:时会发生什么reloadRowsAtIndexPaths:表视图将通过在你的UITableViewDataSource调用tableView:cellForRowAtIndexPath:实现来重新加载这些行。 您可以在那里返回一个单元格,该单元格使用selectedIndex变量来决定它是否应该显示为展开或折叠(对于您的特定应用程序而言,这意味着什么)。 它还会在你的UITableViewDelegate上调用tableView:heightForRowAtIndexPath:是的,这在委托中是愚蠢的)所以如果你的单元格高度改变,这个方法也应该返回一个取决于selectedIndex的值。

另外,我建议你只调用reloadRowsAtIndexPaths:一次,像这样:

 NSMutableArray* rows = [NSMutableArray arrayWithCapacity:2]; // Case 2 if(selectedIndex >= 0) { NSIndexPath* previousPath = [NSIndexPath indexPathForRow:selectedIndex inSection:0]; [rows addObject:previousPath]; } // Case 3 selectedIndex = indexPath.row; [rows addObject:indexPath]; [tableView reloadRowsAtIndexPaths:rows withRowAnimation:UITableViewRowAnimationFade];