如何从UITableView中删除一行 [英] How to delete a row from UITableView

查看:109
本文介绍了如何从UITableView中删除一行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从表格视图中删除一行,但到目前为止一直没有成功。我一直收到这个错误:


由于未捕获的异常终止应用程序
'NSInternalInconsistencyException',原因:'无效更新:无效
第0节中的行数。更新(5)后
现有部分中包含的行数必须等于更新前该部分中包含的
行数( 5),加上或减去
从该部分插入或删除的行数(0插入,
1删除)。'我用来填充表视图的数组是
声明的在那个类中,我也从
sqlite db获取我的数组的对象。


我用过的代码尝试删除行如下。

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

if(editingStyle == UITableViewCellEditingStyleDelete){
//从数据源中删除行

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

}
else if(editingStyle == UITableViewCellEditingStyleInsert){
//创建相应类的新实例,将其插入数组,并向该行添加新行表格视图
}
}

现在我希望得到解答的问题:



- 我如何才能正确删除行?



- 我是否会删除该行,如果它只是tableView中还有一个?



- 我可以将方法中使用的tableView更改为我在
my .h文件中声明的UITableView吗? / p>

非常感谢。






编辑



-Full .m code

  #importDeleteCategoryTableView.h
# importKeyCryptAppAppDelegate.h


@implementation DeleteCategoryTableView
@synthesize categoryArray;

#pragma mark -
#pragma mark初始化

- (void)initializeCategoryArray {

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

const char * sql = [[NSString stringWithFormat:(@从类别中选择类别;)] 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,@错误准备语句,sqlite3_errmsg(db));
}
sqlite3_finalize(compiledStatement);
}
/ *
- (id)initWithStyle:(UITableViewStyle)style {
//覆盖initWithStyle:如果以编程方式创建控制器并想要执行不合适的自定义对于viewDidLoad。
if((self = [super initWithStyle:style])){
}
return self;
}
* /
#pragma mark -
#pragma mark查看生命周期
- (void)viewDidLoad {
self.title = NSLocalizedString(@删除类别,@删除您的类别);
categoryArray = [[NSMutableArray alloc] init];
[self initializeCategoryArray];
[super viewDidLoad];

//取消注释以下行以在此视图控制器的导航栏中显示编辑按钮。
self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
/ *
- (void)viewWillAppear:(BOOL)动画{
[super viewWillAppear:animated];
}
* /
/ *
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
}
* /
/ *
- (void)viewWillDisappear:(BOOL)动画{
[super viewWillDisappear:animated];
}
* /
/ *
- (void)viewDidDisappear:(BOOL)动画{
[super viewDidDisappear:animated];
}
* /
/ *
//覆盖以允许除默认纵向方向以外的方向。
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
//返回YES表示支持的方向
return(interfaceOrientation == UIInterfaceOrientationPortrait);
}
* /


#pragma mark -
#pragma mark表视图数据源

- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {
//返回部分的数量。
返回1;
}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
//返回部分中的行数。
返回[self.categoryArray count];
}


//自定义表格视图单元格的外观。
- (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];
}

//配置单元格...
NSUInteger row = [indexPath row];
cell.text = [categoryArray objectAtIndex:row];
返回单元格;
}
/ *
//覆盖以支持表视图的条件编辑。
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
//如果您不希望指定的项目可编辑,则返回NO。
返回YES;
}
* /
//覆盖以支持编辑表格视图。
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {

if(editingStyle == UITableViewCellEditingStyleDelete){
/ /从数据源中删除行

[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:@从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,@错误准备语句,sqlite3_errmsg(db));
}
sqlite3_finalize(compiledStatement);
}



else if(editingStyle == UITableViewCellEditingStyleInsert){
//创建相应类的新实例,将其插入数组,并在表视图中添加一个新行
}
}
/ *
//覆盖以支持重新排列表格视图。
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
}
* /
/ *
//覆盖以支持表视图的条件重新排列。
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
//如果您不希望该项目可以重新订购,则返回NO。
返回YES;
}
* /
#pragma mark -
#pragma mark表视图委托
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *) indexPath {
//导航逻辑可能会在这里。创建并推送另一个视图控制器。
/ *
<#DetailViewController#> * detailViewController = [[<#DetailViewController#> alloc] initWithNibName:@< #Nib name#>捆绑:无];
// ... ...
//将所选对象传递给新视图控制器。
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
* /
}
#pragma mark -
#pragma mark内存管理

- (void)didReceiveMemoryWarning {
//发布查看它是否没有超视图。
[super didReceiveMemoryWarning];

//放弃所有未使用的缓存数据,图像等的所有权。
}

- (void)viewDidUnload {
//放弃可以在viewDidLoad中或按需重建的任何内容的所有权。
//例如:self.myOutlet = nil;
}


- (无效)dealloc {
[super dealloc];
}


@end


解决方案

1)删除的问题是

  [categoryArray removeObjectAtIndex:indexPath.row]; 

从数据库中删除它。



删除行后,使用 [tableView reloadData]重新加载tableView



2)如果没有问题是唯一的一项



编辑:



这是问题

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

在访问同一indexPath.row的值后,您已从数组中删除了indexPath.row的值,显然它只会删除下一个值.. :)



所以把那个



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



之前的行[categoryArray removeObjectAtIndex:indexPath。 row];


I'm trying to delete a row from my table view and so far have been unsuccessful. I keep getting this error:

"Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (5) must be equal to the number of rows contained in that section before the update (5), plus or minus the number of rows inserted or deleted from that section (0 inserted, 1 deleted).'" The array which i use to populate the table view is declared in that class, also i get my objects for my array from an sqlite db.

The code that i used to try deleting rows is as follows.

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

Now for the questions i hope to get answered:

-How can i delete rows properly?

-Will i face deleting the row if its the only one left in the tableView?

-Can i change the tableView that is used in the method to be the UITableView i declared in my .h file?

Many Thanks.


Edit

-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

解决方案

1) The problem with deleting is

[categoryArray removeObjectAtIndex:indexPath.row];

Remove it from db too.

Once you delete the row, reload the tableView using [tableView reloadData]

2) There is no problem if it is the only one item

Edit:

This is the problem

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

You have deleted the value at indexPath.row from array after that accessing the value at same indexPath.row, obviously it will delete the next value only.. :)

So put that

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

line before [categoryArray removeObjectAtIndex:indexPath.row];

这篇关于如何从UITableView中删除一行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆