我有一個相當簡單的UITableView,其中有20個項目(它們在遊戲中的庫存大小)。我的自定義表格單元格足夠智能以顯示單元格的「SLOT EMPTY」文本代表不包含商品的庫存位置。我有一個工作解決方案,但想知道是否有更好的方法來處理它。從UITableView中刪除項目(不刪除它們)
預期的結果
用戶的庫存可能是這樣的:
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
注該列表在刪除後仍包含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).'
溶液
[注意,在第代碼是部分是從實際代碼爲了清晰而大大簡化 - 問題是關於解決方案的技術,而不是具體的實現細節。]
我最終想到的感覺對我來說有點像黑客,但確實產生預期的結果。
刪除的項目是這樣的:
- (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];
}
這個工作,但是這是實現這一目標的最佳方式是什麼?
我想我只是更新表的支持數據和reloadData - 不要打擾刪除細胞。 –
如何使用最初包含'SLOT%d EMPTY'的20個NSString對象的簡單NSMutableArray,然後開始用您的真實對象替換對象。刪除時,請再次將其替換爲字符串。 –
@HotLicks reloadData的問題在於,您無法將項目從列表中移除。我還遇到過許多其他問題,其中包括單元格移動到表格頂部的一些極其奇怪的結果,並在已位於頂部的單元格後面運行彈跳動畫。很奇怪的東西。 – pauln