删除带有节标题的表视图中的行

Posted

技术标签:

【中文标题】删除带有节标题的表视图中的行【英文标题】:Deleting rows in a tableview with section headers 【发布时间】:2013-10-15 19:25:37 【问题描述】:

在将节标题添加到我的应用程序中的一个表之前,我能够使用 commitEditingStyle 函数删除行。我决定实现部分标题,以便用户更轻松地查看按日期添加到表中的项目。我测试了这个功能,它工作正常。但是现在尝试删除一行会导致崩溃:

-[UITableView _endCellAnimationsWithContext:] 中的断言失败,>/SourceCache/UIKit_Sim/UIKit-2903.2/UITableView.m:1330

我是 obj-c 开发的新手,不愿意添加这些部分,因为我知道这会增加代码的复杂性,我花了一段时间才弄明白。但我想这就是你学习的方式。

下面是 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 deleteRowsAtIndexPaths:@[indexPath]   withRowAnimation:UITableViewRowAnimationFade];
    

【问题讨论】:

你能提供更多的崩溃信息吗? 如果您使用的是 Core Data,那么您真的应该使用 NSFetchedResultsController。看看这个...raywenderlich.com/999/… 【参考方案1】:
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
//replace with it:
[tableView reloadData];

【讨论】:

或者稍微少一点的核选项(更本地化的动画)[tableView reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation: UITableViewRowAnimationAutomatic] 谢谢。因此,在删除具有不同标题部分的行时,上述方法有效(尽管标题部分一直存在,直到我刷新表格然后它们才显示)。但是,如果行在同一部分中,并且我尝试从该部分的第一行开始依次删除多行,则第一行删除正常,但尝试删除第二行会导致应用程序崩溃。如果我按顺序删除第一行以外的所有行,然后最后删除第一行,它工作正常。有什么帮助吗? 解决了崩溃和混乱,但我不得不放弃漂亮的插入/删除动画,所以仍在寻找更好的解决方案。

以上是关于删除带有节标题的表视图中的行的主要内容,如果未能解决你的问题,请参考以下文章

从选定索引处的表视图中的数组中删除

使用Swift 3和CoreData删除表视图行

deleteRowsATIndexPaths 崩溃 [重复]

删除子视图中的核心数据后更新表视图

从 tableview 中删除一行

以编程方式删除数据网格视图中的行标题