5

注意:当我点击该行时,应用程序会崩溃。

我正在尝试在用户的水龙头上添加一个新单元格。我发现在 WWDC 2011 的表格视图演示中有一个类似的例子。这是我的表格视图中的代码。

这是错误:

2013-03-19 20:04:28.672 Project[51229:c07] *** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-2380.17/UITableView.m:1070

这是我在表格视图中的代码。

@interface MyPFQueryTableViewController : PFQueryTableViewController <PFLogInViewControllerDelegate, PFSignUpViewControllerDelegate>

@property (nonatomic, strong) NSIndexPath *controlRowIndexPath;
@property (nonatomic, strong) NSIndexPath *tappedIndexPath;

@implementation MyPFQueryTableViewController {

    ListItemObject *listDetail;
}

@synthesize controlRowIndexPath;
@synthesize tappedIndexPath;


-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        PFObject *object = [self.objects objectAtIndex:indexPath.row];
        [object deleteInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
            [self loadObjects];
        }];
    }

}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object {
    static NSString *CellIdentifier = @"listCell";

    PFTableViewCell *cell = (PFTableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"listCell"];
    if (cell == nil) {
        cell = [[PFTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];


    }

    // Configure the cell
    cell.textLabel.text = [object objectForKey:self.textKey];
    //cell.imageView.file = [object objectForKey:self.imageKey];

    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [super tableView:tableView didSelectRowAtIndexPath:indexPath];

    //if user tapped the same row twice let's start getting rid of the control cell
    if([indexPath isEqual:self.tappedIndexPath]){
        [tableView deselectRowAtIndexPath:indexPath animated:NO];
    }

    //update the indexpath if needed... I explain this below
    indexPath = [self modelIndexPathforIndexPath:indexPath];

    //pointer to delete the control cell
    NSIndexPath *indexPathToDelete = self.controlRowIndexPath;

    //if in fact I tapped the same row twice lets clear our tapping trackers
    if([indexPath isEqual:self.tappedIndexPath]){
        self.tappedIndexPath = nil;
        self.controlRowIndexPath = nil;
    }
    //otherwise let's update them appropriately
    else{
        self.tappedIndexPath = indexPath; //the row the user just tapped.
        //Now I set the location of where I need to add the dummy cell
        self.controlRowIndexPath = [NSIndexPath indexPathForRow:indexPath.row + 1   inSection:indexPath.section];
    }

    //all logic is done, lets start updating the table
    [tableView beginUpdates];

    //lets delete the control cell, either the user tapped the same row twice or tapped another row
    if(indexPathToDelete){
        [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPathToDelete]
                              withRowAnimation:UITableViewRowAnimationNone];
    }
    //lets add the new control cell in the right place
    if(self.controlRowIndexPath){
        [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:self.controlRowIndexPath]
                              withRowAnimation:UITableViewRowAnimationNone];
    }

    //and we are done...
    [tableView endUpdates];
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath   *)indexPath
{
    if([indexPath isEqual:self.controlRowIndexPath]){
        return 45; //height for control cell
    }
    return 70; //height for every other cell
}

- (NSIndexPath *)modelIndexPathforIndexPath:(NSIndexPath *)indexPath
{
    int whereIsTheControlRow = self.controlRowIndexPath.row;
    if(self.controlRowIndexPath != nil && indexPath.row > whereIsTheControlRow)
        return [NSIndexPath indexPathForRow:indexPath.row - 1 inSection:0];
    return indexPath;
}


@end
4

2 回答 2

8

问题出在你的didSelectRowAtIndexPath方法上。你有:

[tableView beginUpdates];

//lets delete the control cell, either the user tapped the same row twice or tapped another row
if(indexPathToDelete){
    [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPathToDelete]
                          withRowAnimation:UITableViewRowAnimationNone];
}
//lets add the new control cell in the right place
if(self.controlRowIndexPath){
    [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:self.controlRowIndexPath]
                          withRowAnimation:UITableViewRowAnimationNone];
}

//and we are done...
[tableView endUpdates];

在您进行任何调用以告诉表添加或删除任何行之前,您必须通过添加或删除数据来更新您的数据源。该表将检查添加/删除行之前和之后有多少部分和行。更改后的部分和行数必须正确反映您添加/删除的数据量以及添加/删除的行数。

当然,您必须实现该numberOfRowsInSection方法。

于 2013-03-20T01:39:59.147 回答
4

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section看起来像什么?

当您尝试在 UITableView 中添加或删除一行时会发生此错误,但是您声称在该方法中更新后该部分中的行数与应加载的新数据不一致。

例如,如果您的 numberOfRowsInSection 始终返回 4 并且您在该部分中添加一行,则 tableView 将希望它为 5,但它不会因此它会崩溃。您需要跟踪每个部分中有多少行并返回该数字。

于 2013-03-20T01:33:10.200 回答