5

注:行をタップすると、アプリがクラッシュします。

ユーザーのタップで新しいセルを追加することを実装しようとしています。WWDC2011のテーブルビューのデモンストレーションにも同様の例があることがわかりました。これが私のテーブルビューからの私のコードです。

エラーは次のとおりです。

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 に答える