Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 从UITableView中删除项目(不删除)_Ios_Uitableview - Fatal编程技术网

Ios 从UITableView中删除项目(不删除)

Ios 从UITableView中删除项目(不删除),ios,uitableview,Ios,Uitableview,我有一个相当简单的UITableView,其中正好有20个项目(它们在游戏中的库存大小)。我的自定义表格单元格足够智能,可以为表示不包含项目的库存插槽的单元格显示“插槽空”文本。我有一个有效的解决方案,但我想知道是否有更好的方法来处理它 预期结果 用户的清单可能如下所示: Bellybutton fuzz Petrified weasel snout Chocolate covered toilet seat Coupon for a high-five from Chase SLOT 5 EM

我有一个相当简单的UITableView,其中正好有20个项目(它们在游戏中的库存大小)。我的自定义表格单元格足够智能,可以为表示不包含项目的库存插槽的单元格显示“插槽空”文本。我有一个有效的解决方案,但我想知道是否有更好的方法来处理它

预期结果

用户的清单可能如下所示:

Bellybutton fuzz
Petrified weasel snout
Chocolate covered toilet seat
Coupon for a high-five from Chase
SLOT 5 EMPTY
SLOT 6 EMPTY
.
.
.
SLOT 20 EMPTY
Bellybutton fuzz
Petrified weasel snout
Coupon for a high-five from Chase
SLOT 4 EMPTY
SLOT 5 EMPTY
.
.
.
SLOT 20 EMPTY
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete)
    {
        NSDictionary *item = [self itemForRowAtIndexPath:indexPath];
        if (!item) return;

        // Keep track of the deleted item count
        self.mDeletedEntries += 1;

        [tableView beginUpdates];
        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationTop];
        [tableView endUpdates];

        // Remove it from the data store
        [Inventory removeInventoryItem:item];
    }
}
如果用户删除马桶座圈,则列表应如下所示:

Bellybutton fuzz
Petrified weasel snout
Chocolate covered toilet seat
Coupon for a high-five from Chase
SLOT 5 EMPTY
SLOT 6 EMPTY
.
.
.
SLOT 20 EMPTY
Bellybutton fuzz
Petrified weasel snout
Coupon for a high-five from Chase
SLOT 4 EMPTY
SLOT 5 EMPTY
.
.
.
SLOT 20 EMPTY
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete)
    {
        NSDictionary *item = [self itemForRowAtIndexPath:indexPath];
        if (!item) return;

        // Keep track of the deleted item count
        self.mDeletedEntries += 1;

        [tableView beginUpdates];
        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationTop];
        [tableView endUpdates];

        // Remove it from the data store
        [Inventory removeInventoryItem:item];
    }
}
注意,在删除后,列表仍然包含20个单元格,使用的单元格向上移动以占据库存的前三个插槽

问题

我最初的尝试是使用
[tableView deleteRowsAtIndexPaths:withRowAnimation:
并调整我的备份数据以反映新内容(少一个库存项目,多一个空槽)。但是,这导致崩溃,出现以下异常:

*** 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 (20) must be equal to the number
of rows contained in that section before the update (20), plus or minus the number
of rows inserted or deleted from that section (0 inserted, 1 deleted) and plus or
minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'
解决方案(?)

[请注意,为了清晰起见,本节中的代码大大简化了实际代码-问题在于解决方案技术,而不是具体的实现细节。]

我最后想到的东西对我来说有点像黑客,但确实产生了预期的结果

删除项目的操作如下所示:

Bellybutton fuzz
Petrified weasel snout
Chocolate covered toilet seat
Coupon for a high-five from Chase
SLOT 5 EMPTY
SLOT 6 EMPTY
.
.
.
SLOT 20 EMPTY
Bellybutton fuzz
Petrified weasel snout
Coupon for a high-five from Chase
SLOT 4 EMPTY
SLOT 5 EMPTY
.
.
.
SLOT 20 EMPTY
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete)
    {
        NSDictionary *item = [self itemForRowAtIndexPath:indexPath];
        if (!item) return;

        // Keep track of the deleted item count
        self.mDeletedEntries += 1;

        [tableView beginUpdates];
        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationTop];
        [tableView endUpdates];

        // Remove it from the data store
        [Inventory removeInventoryItem:item];
    }
}
然后,我将替换丢失的项目:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // If we have deleted some entries and need to add some new ones, schedule
    // a process to insert them.
    //
    // *This is what feels like a hack to me*
    if (self.mDeletedEntries)
    {
        [self performSelector:@selector(addEmptySlots:) withObject:tableView afterDelay:0];
    }

    // Return the current count that IOS wants (inventory size minus the deleted ones)
    return kUserMaxInventorySize - self.mDeletedEntries;
}

- (void)addEmptySlots:(UITableView *)tableView
{
    // We start adding entries into the list at the end
    int insertLocation = kUserMaxInventorySize - self.mDeletedEntries;

    [tableView beginUpdates];

    // Add the deleted entries (should only ever be 1 entry, really)    
    for (int i = 0; i < self.mDeletedEntries; ++i)
    {
        // They get added to the end of the table
        NSIndexPath *path = [NSIndexPath indexPathForRow:insertLocation + i inSection:0];
        NSArray *indexArray = [NSArray arrayWithObjects:path,nil];

        // Insert the entry. We don't need to actually add the item to our data store,
        // since empty entries will simply report "Slot empty" text.
        [tableView insertRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationBottom];
    }

    // These are no longer deleted
    self.mDeletedEntries = 0;

    [tableView endUpdates];
}
-(NSInteger)表视图:(UITableView*)表视图行数节:(NSInteger)节
{
//如果我们删除了一些条目,需要添加一些新条目,请安排
//插入它们的过程。
//
//*这对我来说就像是一个黑客*
if(self.mDeletedEntries)
{
[self-performSelector:@selector(addEmptySlots:)with object:tableView afterDelay:0];
}
//返回IOS想要的当前计数(库存大小减去已删除的数量)
返回kUserMaxInventorySize-self.mDeletedEntries;
}
-(无效)addEmptySlots:(UITableView*)tableView
{
//我们开始在列表末尾添加条目
int insertLocation=kUserMaxInventorySize-self.mDeletedEntries;
[tableView开始更新];
//添加删除的条目(实际上应该只有一个条目)
对于(int i=0;i

这是可行的,但这是实现这一点的最佳方式吗?

我认为您的方法使这一点变得更加复杂。例如,您说过您的tableview将始终正好有20个单元格。为什么“-(NSInteger)tableView:(UITableView*)tableView numberofrowsinssection:(NSInteger)section”不简单地返回20

我真的不确定你是如何在库存中储存这些物品的。我只是想写我的例子,就好像你有一个名为inventory的NSMutableArray一样

我总是返回20作为行数

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 20;
}
cellforrowatinexpath
中,检查要创建单元格的行中是否存在项,或者是否应创建“插槽空”单元格:


我想我应该更新表的备份数据并重新加载数据——不用费心删除单元格。一个简单的NSMutableArray,包含20个NSString对象,其中包含
插槽%d EMPTY
,然后开始用实际对象替换对象。删除时,请再次用字符串替换它。@HotLicks重新加载数据的问题是,您失去了从列表中设置项目动画的能力。我也有很多其他的问题,包括一些非常奇怪的结果,从细胞移动到表的顶部,并在已经在顶部的细胞后面运行一个反弹动画。非常奇怪的东西。谢谢亚历克斯!你完全正确-我根本没有想到在删除库存项目的更新过程中插入条目。在我的例子中,技巧是在最后一个实际库存项目(删除后)之后立即插入新条目,而不是在列表的末尾。不过,这是特定于实现的。我很高兴能提供帮助!