将节标题添加到uitableview后删除行的问题
Posted
技术标签:
【中文标题】将节标题添加到uitableview后删除行的问题【英文标题】:Issue with deleting rows after adding section header to uitableview 【发布时间】:2013-10-17 13:19:45 【问题描述】:在将节标题添加到我的应用程序中的一个表之前,我能够使用 commitEditingStyle 函数删除行而没有任何问题。我决定实现部分标题,以便用户更轻松地查看按日期添加到表中的项目。此功能工作正常。在实现节标题后,我在删除行时遇到了问题,但感谢 *** 上好心人的帮助,问题得到了部分解决。经过一些测试,我意识到如果这些行在同一部分中,并且我尝试从该部分的第一行开始依次删除多行,则第一行删除得很好,但尝试删除第二行会导致应用程序崩溃。如果我按顺序删除第一行以外的所有行,然后最后删除第一行,它工作正常。 Xcode 没有在调试日志中指出它崩溃的原因。
下面是 cellForRowAtIndexPath 函数的代码:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
static NSString *CellIdentifier = @"Cell";
AgendaCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
cell = [[AgendaCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
NSString *strDate = [dateArray objectAtIndex:indexPath.section];
NSMutableArray *dateSection = [tempDict objectForKey:strDate];
NSManagedObject *object = [dateSection objectAtIndex:indexPath.row];
cell.sessionNameLabel.text = [object valueForKey:@"sessionname"];
cell.sessionNameLabel.textColor = [UIColor blueColor];
cell.sessionDateLabel.text = [object valueForKey:@"sessiondate"];
cell.sessionDateLabel.textColor = [UIColor brownColor];
cell.sessionTimeLabel.text = [object valueForKey:@"sessiontime"];
cell.sessionTimeLabel.textColor = [UIColor brownColor];
return cell;
这是我的表格刷新功能的代码:
- (void) refreshTable
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Edit the entity name as appropriate.
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Sessnotes" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"agenda == 'Yes'"]];
// Edit the sort key as appropriate.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"sessiondate" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
NSArray *results = [self.managedObjectContext executeFetchRequest:fetchRequest error:nil];
[self.refreshControl endRefreshing];
self.objects = results;
if (results.count == 0)
NSString *message = @"You have not added any sessions to your planner.";
UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:@"Notification"
message:message
delegate:self
cancelButtonTitle:@"Ok"
otherButtonTitles:nil,nil];
[alertView show];
else if (results.count > 0)
tempDict = nil;
tempDict = [[NSMutableDictionary alloc] init];
NSString *strPrevDate= [[results objectAtIndex:0] valueForKey:@"sessiondate"];
NSLog(@"strPrevDate value is: %@", strPrevDate);
NSString *strCurrDate = nil;
NSMutableArray *tempArray = [[NSMutableArray alloc] init];
//Add the Similar Date data in An Array then add this array to Dictionary
//With date name as a Key. It helps to easily create section in table.
for(int i=0; i< [results count]; i++)
strCurrDate = [[results objectAtIndex:i] valueForKey:@"sessiondate"];
if ([strCurrDate isEqualToString:strPrevDate])
[tempArray addObject:[results objectAtIndex:i]];
else
[tempDict setValue:[tempArray copy] forKey:strPrevDate];
strPrevDate = strCurrDate;
[tempArray removeAllObjects];
[tempArray addObject:[results objectAtIndex:i]];
//Set the last date array in dictionary
[tempDict setValue:[tempArray copy] forKey:strPrevDate];
NSArray *tArray = [tempDict allKeys];
//Sort the array in ascending order
dateArray = [tArray sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
[self.tableView reloadData];
这里是 commitEditingStyle 函数的代码:
- (void)tableView:(UITableView *)tableView commitEditingStyle: (UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
if (editingStyle == UITableViewCellEditingStyleDelete)
//add code here for when you hit delete
NSManagedObject *object = [self.objects objectAtIndex:indexPath.row];
NSManagedObjectContext *context = [self managedObjectContext];
[context deleteObject:[context objectWithID:[object objectID]]];
NSError *error = nil;
// Save the object to persistent store
if (![context save:&error])
NSLog(@"Can't Save! %@ %@", error, [error localizedDescription]);
NSMutableArray *array = [self.objects mutableCopy];
[array removeObjectAtIndex:indexPath.row];
self.objects = array;
[tableView reloadData];
【问题讨论】:
【参考方案1】:前面有几件事。每次您想重新加载 tableview 时,我都不会发出 fetch 请求。你应该看看 NSFetchedResultsController。它会自动将数据绑定到您的 tableview 并根据来自相同 NSManagedObjectContexts 的更新或来自其他上下文的更新消息为您进行刷新,并为您批处理它们。
回答你原来的问题。我会尝试先从数组中删除对象,然后删除 NSManagedObject,然后你可以使用一些 tableview 技巧:
NSManagedObject *managedObject = self.array[indexPath.row];
[self.array removeObjectAtIndex:indexPath.row];
[self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation: UITableViewRowAnimationAutomatic];
[context deleteObject:managedObject];
我可能是错的,但有可能你没有完成一个错误。希望对您有所帮助。
【讨论】:
以上是关于将节标题添加到uitableview后删除行的问题的主要内容,如果未能解决你的问题,请参考以下文章
尝试将节页脚添加到 UICollectionView 时崩溃
将视图添加/删除到表视图的超级视图后,UITableView 停止滚动
用于在 Swift 中删除 UITableView 中的行的编辑按钮不起作用