Ios 在tableView中插入和删除行时,如何防止它尝试在无效位置添加行?
假设我有一个tableView部分,只有两个单元格,用户名和密码。如果我点击这些单元格中的任何一个,我想在它们的正下方添加另一个单元格(包含有效用户名的信息等)。一次只能看到一个详细信息单元格,因此如果用户名单元格打开,我点击密码,用户名单元格将被删除,密码单元格将被添加 我遇到了一个问题,如果用户名是打开的,我点击密码,应用程序崩溃。它试图在indexath.row 3插入一个单元格(因为当时,用户名在0,用户名详细信息在1,密码在2。但是,刚刚发生了一次删除,到那时用户名详细信息消失了,所以它试图在3插入,而实际上应该在2插入 我能在这里做什么?这整个细胞更新的事情看起来非常复杂,因为这应该是一个简单的操作Ios 在tableView中插入和删除行时,如何防止它尝试在无效位置添加行?,ios,objective-c,uitableview,Ios,Objective C,Uitableview,假设我有一个tableView部分,只有两个单元格,用户名和密码。如果我点击这些单元格中的任何一个,我想在它们的正下方添加另一个单元格(包含有效用户名的信息等)。一次只能看到一个详细信息单元格,因此如果用户名单元格打开,我点击密码,用户名单元格将被删除,密码单元格将被添加 我遇到了一个问题,如果用户名是打开的,我点击密码,应用程序崩溃。它试图在indexath.row 3插入一个单元格(因为当时,用户名在0,用户名详细信息在1,密码在2。但是,刚刚发生了一次删除,到那时用户名详细信息消失了,所以
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSIndexPath *indexPathToDelete = self.controlRowIndexPath;
if ([indexPath isEqual:self.tappedIndexPath]) {
[tableView deselectRowAtIndexPath:indexPath animated:NO];
self.tappedIndexPath = nil;
self.controlRowIndexPath = nil;
if (indexPath.section == 0) self.cellDetailOpenInSection0 = NO;
else if (indexPath.section == 1) self.cellDetailOpenInSection1 = NO;
else self.cellDetailOpenInSection2 = NO;
} else {
self.tappedIndexPath = indexPath;
self.controlRowIndexPath = [NSIndexPath indexPathForRow:indexPath.row + 1 inSection:indexPath.section];
if (indexPath.section == 0) self.cellDetailOpenInSection0 = YES;
else if (indexPath.section == 1) self.cellDetailOpenInSection1 = YES;
else self.cellDetailOpenInSection2 = YES;
}
[self.userPassTableView beginUpdates];
if (indexPathToDelete) {
[self.userPassTableView deleteRowsAtIndexPaths:@[indexPathToDelete] withRowAnimation:UITableViewRowAnimationAutomatic];
if (indexPathToDelete.section == 0) self.cellDetailOpenInSection0 = NO;
else if (indexPathToDelete.section == 1) self.cellDetailOpenInSection1 = NO;
else if (indexPathToDelete.section == 2) self.cellDetailOpenInSection2 = NO;
}
if (self.controlRowIndexPath) {
[self.userPassTableView insertRowsAtIndexPaths:@[self.controlRowIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
if (self.controlRowIndexPath.section == 0) self.cellDetailOpenInSection0 = YES;
else if (self.controlRowIndexPath.section == 1) self.cellDetailOpenInSection1 = YES;
else if (self.controlRowIndexPath.section == 2) self.cellDetailOpenInSection2 = YES;
}
// Trying to insert one at a location that no longer exists because it just deleted one.
[self.userPassTableView endUpdates];
}
好吧,如果只有两个单元格,你就不需要把它弄得太复杂了。我要做的是使用
heightforrowatinexpath:
和begin/end updates来帮我完成繁重的工作
首先,设置每个单元格,使其上半部分显示用户名/密码标签/文本字段/您想要的任何内容,下半部分显示“详细信息”
然后只需修改heightForRowAtIndexPath:
,默认情况下返回一个值,该值只会显示单元格的上半部分,并且只会有条件地大到足以显示整个单元格。从这里开始,您只需进行一点indexPath比较,您就成功了
- (void)viewDidLoad
{
[super viewDidLoad];
self.currentIndexPath = [NSIndexPath indexPathForRow:NSIntegerMax inSection:0];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([indexPath compare:self.currentIndexPath] == NSOrderedSame) {
return 100.0f;
}
return 44.0f;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.tableView beginUpdates];
if ([indexPath compare:self.currentIndexPath] == NSOrderedSame) {
self.currentIndexPath = [NSIndexPath indexPathForRow:NSIntegerMax inSection:0];
}else{
self.currentIndexPath = [NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section];
}
[self.tableView endUpdates];
}
你能分享数据源委托方法吗?比如numberOfRowsInSection:请。这样我就可以消除对你问题的疑虑。我尝试了两种解决方案(改变高度/插入和删除)而且改变高度要容易得多。插入和删除单元格会带来很多问题,因为所有的索引都在不断变化。@Sulthan确实如此,特别是当只有两个单元格需要担心的时候。我将稍微考虑一下这种方法。实际上有三个组,两个组中的两个,三个组中的一个。@lukech好的,让我e知道它是如何运行的!如果这是您使用的单元格数量,您仍然需要担心此方法的性能。但是,如果您想进一步优化,您可以将此解决方案与原始解决方案混合使用。可能会动态创建包含该单元格详细信息的视图,并仅在选定单元格时添加该视图,然后在取消选择时将其删除。这可能通过对单元格进行子类化很容易实现。更好。我还有几根头发,我以你的名字命名它们。