Удаление записей в UITableViewController выдает ошибку - PullRequest
0 голосов
/ 27 августа 2011

Проблема: Когда я нажимаю кнопку удаления для данной строки таблицы / раздела, я получаю следующую ошибку: «*** Завершение работы приложения из-за необработанного исключения« NSInternalInconsistencyException », причина:« Неверное обновление: недопустимое количество строк в раздел 0. Количество строк, содержащихся в существующем разделе после обновления (4), должно быть равно количеству строк, содержащихся в этом разделе до обновления (4), плюс или минус количество строк, вставленных или удаленных из этого раздела. (0 вставлено, 1 удалено). '"

enter image description here

Из других постов, которые я читал об этом признаке, я полагаю, что я предполагаю, что вручную удаляю элемент из моего массива источника данных, но не уверен, как получить доступ к массиву раздела внутри этого метода:

// COMMIT EDITING STYLE
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(@"indexPath: %@", indexPath);    

if (editingStyle == UITableViewCellEditingStyleDelete) {
    // Delete the row from the data source        
   [tableView beginUpdates];
    [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
    [tableView endUpdates]; // throws error here
    [tableView reloadData];   
}   
else if (editingStyle == UITableViewCellEditingStyleInsert) {
    // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}   

}

Я думаю, что осложнение для этой ситуации возникает из-за того, что plist (FormEntries.plist), который я извлекаю из данных, хранит пользовательский ввод для всех видов вещей во всем приложении, поэтому мне приходится вызывать и фильтровать это для каждого раздела. Это прекрасно работает для заполнения UITableView и всех его разделов, но поскольку новый и отфильтрованный массив создается для каждого раздела и внутри него, я не уверен, как получить к нему доступ снова, чтобы удалить элемент, тем самым исправляя вышеупомянутое. сообщение об ошибке. Вот как я загружаю данные для каждого раздела таблицы:

// CELL FOR ROW AT INDEXPATH
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath (NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";    
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}

NSNumber *numScreenId = [[arrayOfModulesScreens objectAtIndex: indexPath.section] objectForKey: @"id"];
NSMutableArray *arrayRecords = [epFrameWork selectPlist: @"FormEntries" filterByKey: @"screen_id" keyValue:numScreenId];

NSString *strTitle = [[arrayRecords objectAtIndex: indexPath.row] objectForKey: @"storage_string"];

cell.textLabel.text = strTitle;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;           
return cell;

}

- Не уверен, что это поможет диагностировать вещи, но здесь это не менее ---

// TITLE FOR HEADER IN SECTION
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return [[arrayOfModulesScreens objectAtIndex: section] objectForKey: @"screen_title"];
}

// NUMBER OF SECTIONS IN TABLE VIEW 
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [arrayOfModulesScreens count];
}


// NUMBER OF ROWS IN SECTION
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSNumber *numScreenId = [[arrayOfModulesScreens objectAtIndex: section] objectForKey: @"id"];
NSMutableArray *arrayRecords = [epFrameWork selectPlist: @"FormEntries" filterByKey: @"screen_id" keyValue:numScreenId];
int rowCount = [arrayRecords count];
return rowCount;    
}

Как лучше всего справиться с этой ситуацией или разрешить опубликованное выше сообщение об ошибке?

- ОБНОВЛЕНИЕ -

Итак, вот как я пытаюсь определить, какую запись plist следует удалить, предполагая, что это то, что мне нужно сделать, чтобы устранить исходную ошибку:

 - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{

int g = indexPath.row;
int count = -1;
UITableViewCell *tvc = [[UITableViewCell alloc] init];
for(id element in tableView.subviews) {
    if([element isKindOfClass:[UITableViewCell class]]) {
       count +=1; 
        NSLog(@"g: %d - count: %d", g , count);
        if(count == g) {
            tvc = element;
            NSLog(@"tvc: %@ - UID: %@ - g: %d - count: %d", tvc, tvc.detailTextLabel.text, g , count);
        }
    }
}

Моя логика заключалась в том, чтобы установить скрытый уникальный идентификатор для tvc.detailTextLabel.text в методе cellForRowAtIndexPath, который, в свою очередь, дал бы мне знать, какую запись из plist фильтровать и удалять, вызывая [array removeObjectAtIndex: uid] где array мой отфильтрованный массив списков. Единственная проблема сейчас заключается в том, что tvc в NSLog всегда возвращает запись с индексом 0, а не строку, в которой находится кнопка удаления, которую я нажимаю.

NSLog возвращает: tvc: > - UID: -237206321 - g: 3 - count: 3. Так почему бы tvc вернуть индекс 0, когда он был индексом 3 Я нажал кнопку удаления?

Это просто превращается в кластерный беспорядок или есть более чистое решение? Но ты все еще в тупике.

Ответы [ 2 ]

0 голосов
/ 27 августа 2011

Вот как я наконец смог решить проблему:

Я изменил все это дерьмо:

int g = indexPath.row;
int count = -1;
UITableViewCell *tvc = [[UITableViewCell alloc] init];
for(id element in tableView.subviews) {
if([element isKindOfClass:[UITableViewCell class]]) {
   count +=1; 
    NSLog(@"g: %d - count: %d", g , count);
    if(count == g) {
        tvc = element;
        NSLog(@"tvc: %@ - UID: %@ - g: %d - count: %d", tvc, tvc.detailTextLabel.text, g , count);
    }
  }
}

до одной простой строки:

UITableViewCell *cell = [[self tableView] cellForRowAtIndexPath:indexPath];   

Это позволило мне идентифицировать камеру, с которой я работал. Итак, мой окончательный код, который работал, выглядит так:

// COMMIT EDITING STYLE
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{

if (editingStyle == UITableViewCellEditingStyleDelete) {
    UITableViewCell *cell = [[self tableView] cellForRowAtIndexPath:indexPath];        
    [epFrameWork deleteRecordFromPlist:@"FormEntries" uid:cell.detailTextLabel.text];        
    [tableView reloadData];         

}   
else if (editingStyle == UITableViewCellEditingStyleInsert) {
    // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
 }   
}

-(void) deleteRecordFromPlist:(NSString *)plist uid:(NSString *)uId {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *tmpFileName = [[NSString alloc] initWithFormat:@"%@.plist", plist];
NSString *path = [documentsDirectory stringByAppendingPathComponent:tmpFileName];
NSMutableArray *array = [[NSMutableArray alloc] initWithContentsOfFile:path];
NSDictionary *dict = [[NSDictionary alloc] init];
NSString *tmpUid;
for(int i=0; i < [array count]; i++) {
    dict = [array objectAtIndex:i];
    tmpUid = [dict valueForKey:@"uid"];
    if([tmpUid isEqualToString:uId]) {
       [array removeObjectAtIndex:i];
       [array writeToFile:path atomically:YES];
    }
  }
}
0 голосов
/ 27 августа 2011

Эта ошибка наиболее определенно связана с неправильным обращением с данными, которые вы пытаетесь загрузить в свою таблицу.Я обнаружил, что самый простой и безопасный способ изменения содержимого таблицы - это выполнить что-то в этом направлении с необходимыми настройками (в пределах tableView: commitEditingStyle:)

    //REMOVE A CELL FROM A SECTION 

    [yourTable beginUpdates];
    [yourTable deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationBottom];
    [yourTable endUpdates];
    [yourTable reloadData];

Кроме того, вам необходимо убедиться, что вашмассив правильно обновлен, чтобы изменения отображались в таблице.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...