Подтвердить что ты не робот

Как удалить строку из UITableView

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

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

Код, который я использовал для удаления строк, выглядит следующим образом.

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

if (editingStyle == UITableViewCellEditingStyleDelete) {
    // Delete the row from the data source

    [categoryArray objectAtIndex:indexPath.row];
    [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES];

}   
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
}   
}

Теперь для вопросов, на которые я надеюсь получить ответ:

-Как я могу правильно удалить строки?

-Убеду ли я удалить строку, если она осталась только в таблицеView?

-Can я изменить tableView, который используется в методе как UITableView i, объявленный в мой файл .h?

Большое спасибо.


Изменить

-Full.m code

#import "DeleteCategoryTableView.h"
#import "KeyCryptAppAppDelegate.h"


@implementation DeleteCategoryTableView
@synthesize categoryArray;

#pragma mark -
#pragma mark Initialization

-(void) initializeCategoryArray {

sqlite3 *db= [KeyCryptAppAppDelegate getNewDBConnection];
KeyCryptAppAppDelegate *appDelegate = (KeyCryptAppAppDelegate *)[[UIApplication sharedApplication] delegate];

const char *sql = [[NSString stringWithFormat:(@"Select Category from Categories;")]cString];


sqlite3_stmt *compiledStatement;



if (sqlite3_prepare_v2(db, sql, -1, &compiledStatement, NULL)==SQLITE_OK)
{
    while(sqlite3_step(compiledStatement) == SQLITE_ROW)
        [categoryArray addObject:[NSString stringWithUTF8String:(char*) sqlite3_column_text(compiledStatement, 0)]];

}
else {
    NSAssert1(0,@"Error preparing statement", sqlite3_errmsg(db));
}
sqlite3_finalize(compiledStatement);
}
/*
- (id)initWithStyle:(UITableViewStyle)style {
// Override initWithStyle: if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
if ((self = [super initWithStyle:style])) {
}
return self;
}
*/
#pragma mark -
#pragma mark View lifecycle
- (void)viewDidLoad {
self.title = NSLocalizedString(@"Delete Categories",@"Delete your Categories");
categoryArray = [[NSMutableArray alloc]init];
[self initializeCategoryArray];
[super viewDidLoad];

// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
/*
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
}
*/
/*
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
}
*/
/*
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
}
*/
/*
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
}
*/
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/


#pragma mark -
#pragma mark Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section    {
// Return the number of rows in the section.
return [self.categoryArray count];
}


// Customize the appearance of table view cells.
- (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];
}

// Configure the cell...
NSUInteger row = [indexPath row];
cell.text = [categoryArray objectAtIndex:row];
return cell;
}
/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the specified item to be editable.
return YES;
}
*/
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {

if (editingStyle == UITableViewCellEditingStyleDelete) {
    // Delete the row from the data source

    [categoryArray removeObjectAtIndex:indexPath.row];
    [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES];
    [deleteCategoryTable reloadData];

    NSString *selectedCategory = [categoryArray objectAtIndex:indexPath.row];

    sqlite3 *db= [KeyCryptAppAppDelegate getNewDBConnection];
    KeyCryptAppAppDelegate *appDelegate = (KeyCryptAppAppDelegate *)[[UIApplication sharedApplication] delegate];
    const char *sql = [[NSString stringWithFormat:@"Delete from Categories where Category = '%@';", selectedCategory]cString];

    sqlite3_stmt *compiledStatement;


    if (sqlite3_prepare_v2(db, sql, -1, &compiledStatement, NULL)==SQLITE_OK)
    {
        sqlite3_exec(db,sql,NULL,NULL,NULL);

    }
    else {
        NSAssert1(0,@"Error preparing statement", sqlite3_errmsg(db));
    }
    sqlite3_finalize(compiledStatement);
}



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
}   
}
/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
}
*/
/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/
#pragma mark -
#pragma mark Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Navigation logic may go here. Create and push another view controller.
/*
 <#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:@"<#Nib name#>" bundle:nil];
 // ...
 // Pass the selected object to the new view controller.
 [self.navigationController pushViewController:detailViewController animated:YES];
 [detailViewController release];
 */
}
#pragma mark -
#pragma mark Memory management

- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];

// Relinquish ownership any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
// Relinquish ownership of anything that can be recreated in viewDidLoad or on demand.
// For example: self.myOutlet = nil;
}


- (void)dealloc {
[super dealloc];
}


@end
4b9b3361

Ответ 1

1) Проблема с удалением

[categoryArray removeObjectAtIndex:indexPath.row];

Удалите его и из db.

Как только вы удалите строку, перезагрузите tableView с помощью [tableView reloadData]

2) Нет проблем, если это единственный элемент

Edit:

Это проблема

[categoryArray removeObjectAtIndex:indexPath.row];
NSString *selectedCategory = [categoryArray objectAtIndex:indexPath.row];

Вы удалили значение в indexPath.row из массива после доступа к значению в том же indexPath.row, очевидно, что оно удалит только следующее значение.:)

Итак, поставьте

NSString *selectedCategory = [categoryArray objectAtIndex:indexPath.row]

перед [categoryArray removeObjectAtIndex:indexPath.row];

Ответ 2

Это ВСЕ, которые вам нужно сделать. Это позволяет реализовать один метод достаточно хорошо.

Swift 2

func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
    if editingStyle == .Delete {

        //1. remove data from model
        data.removeAtIndex(indexPath.row) 

        //2. remove row from view
        tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade) 

        //3. custom method to update your view after removing
        updateView() 
    }
}

Swift 3

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
    if editingStyle == .delete {

        //1. remove data from model
        data.remove(at: indexPath.row)

        //2. remove row from view
        tableView.deleteRows(at: [indexPath as IndexPath], with: .fade)

        //3. custom method to update your view after removing
        updateView()
    }
}

Ответ 3

для этой цели не пытайтесь удалить строку, попробуйте удалить из массива или источника данных (в случае, если массив готовится из базы данных), тогда попробуйте перезагрузить массив, просто вызовите функцию базы данных.

затем

[table reloadData].

это правильная практика.

Ответ 4

Ваш код в порядке, ожидайте, что withRowAnimation: не ожидает член BOOL, но UITableViewRowAnimation. Например. UITableViewRowAnimationRight, чтобы он скользил в правую сторону таблицы.

Также: вы просто извлекаете объект из массива, его нужно удалить! Если это измененный массив, вы можете использовать [categoryArray removeObjectAtIndex:indexpath.row]

Ответ 5

Прочитайте, что проблема с консоли.

У вас есть метод numberOfRowsInSection... позволяет указать его значение return 5;.

Когда вы удаляете строку из представления таблицы, вам также необходимо обновить этот метод... поэтому он ищет вас в return 4; из этого метода.

В основном вам нужно убедиться, что количество строк в представлении таблицы равно ONE LESS, чем до того, как вы удалили свою строку.