2010-01-13 189 views
0

我有一個表格顯示來自單個數組的數據,並根據一組過濾器將項目組織到單獨的部分。每個過濾器都有相應的部分。我的用戶界面允許用戶點擊每個表格單元格中嵌入的複選框。該複選框設置一個「檢查」標誌,該標誌影響該項目被過濾到的部分。下面是一個例子:當更新更改單元格的單元格時UITableView崩潰

  • 第一節
    • 項A
    • 項B
  • 第2節
  • 節 「完成」

攻絲旁邊的複選框到項目A應導致表格重新排列以查看像這樣:

  • 第一節
    • 項B
  • 第2節
  • 節 「完成」
    • 項A

下面是我的代碼,用於響應複選框點擊。它計算出該複選框屬於哪一行,然後嘗試創建一個動畫塊,該動畫塊從其舊部分中刪除該行,並在「完成」部分的末尾添加一行。請記住,數組並沒有真正改變 - 數據被過濾到部分的方式會根據項目檢查屬性的值而改變。

- (IBAction)checkBoxTapped:(id)sender 
{ 
// Get the table cell 
CheckBoxControl* checkBox = (CheckBoxControl*)sender; 

UITableViewCell* cell = (UITableViewCell*)[[sender superview] superview]; 
UITableView* table = (UITableView*)[cell superview]; 
NSIndexPath* indexPath = [table indexPathForCell:cell]; 

Item* item = [self itemAtRow:[indexPath row] inSection:[indexPath section]]; 
item.checked = checkBox.checked; 

Filter* filter = [filters objectAtIndex:DONE_INDEX]; 
// We want the new row at the bottom of the "Done" section. 
NSIndexPath* newIndexPath = [NSIndexPath indexPathForRow:[self countItemsWithFilter:filter] inSection:DONE_INDEX]; 

[table beginUpdates]; 
[table insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade]; 
[table deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
[table endUpdates]; 
} 

該代碼總是拋出異常:

2010-01-13 00:19:44.802 MyApp[19923:207] *** Terminating app due to uncaught 
exception 'NSRangeException', reason: 
'*** -[NSMutableIndexSet addIndexesInRange:]:Range {2147483647, 1} 
exceeds maximum index value of NSNotFound - 1' 

誰能幫我找出是什麼原因造成的NSRangeException?這裏是我的籌碼:

___TERMINATING_DUE_TO_UNCAUGHT_EXCEPTION___ 
obj_exception_throw 
+[NSException raise:format:arguments:] 
+[NSException raise:format:] 
-[NSMutableIndexSet addIndexesInRange:] 
-[NSMutableIndexSet addIndex:] 
-[_UITableViewUpdateSupport(Private) _computeRowUpdates] 
-[_UITableViewUpdateSupport initWithTableView:updateItems:oldRowData:oldRowRange:newRowRange:context:] 
-[UITableView(_UITableViewPrivate) _updateWithItems:withOldRowData:oldRowRange:newRowRange:context:] 
-[UITableView(_UITableViewPrivate) _endCellAnimationsWithContext:] 
-[UITableView endUpdates] 
-[RootViewController checkBoxTapped:] 

如果此代碼是完全錯誤那我應該怎麼動畫從一個部分移除一行並將其添加到另一個?

在此先感謝您提供的任何幫助。

-Mike-

回答

1

好吧,我想我找到了一個更好的方法。我決定爲每個部分創建一個數組,而不是試圖使用過濾函數填充這些部分。每個部分的數組包含數據源數組中的索引。它看起來是這樣的:

NSArray* data = [[NSArray alloc] initWithObjects:@"Apple", @"Banana", @"Cat", @"Dog", nil]]; 
NSMutableArray* doneFilter = [[NSMutableArray alloc] init]; 
NSMutableArray* othersFilter = [[NSMutableArray alloc] initWithObjects:[NSNumber numberWithInt:0], 
           [NSNumber numberWithInt:1], [NSNumber numberWithInt:2], 
           [NSNumber numberWithInt:3], nil]; 

現在,當用戶點擊複選框我從othersFilter刪除項目的索引,並將其添加到doneFilter的底部。然後我刪除並在表格視圖中添加相應的行。這看起來比我以前更穩定(沒有拋出異常!!),並具有允許過濾器自己排序的額外好處。

0

調用-insertRowsAtIndexPaths-deleteRowsAtIndexPaths你只告訴UITableView的動畫更新對應的行。所以可能的問題是,你也應該相應地更新你的數據源到你的改變(例如-numberOfRowsInSection必須返回實際值等)

+0

我寫了-numberOfRowsInSection來詢問該部分的過濾器有多少項匹配。在調用-insertRowsAtIndexPaths和-deleteRowsAtIndexPaths之前,項目的「checked」屬性發生更改,因此過濾器將報告每個部分的正確項目數。我在-numberOfRowsInSection中放置了一個斷點並驗證了這一點。 我設計了數據源,所以數組沒有被修改。每個部分顯示來自數組的相同副本的項目,篩選器根據項目的值確定每個部分顯示哪些項目。那有意義嗎? – 2010-01-13 19:57:21

+0

是的這種方式看起來不錯,它的工作? :) – Vladimir 2010-01-14 08:06:56

+0

不,當我嘗試我每次都得到例外。我在測試環境中嘗試了一些其他方法,以查看是否可以縮小範圍。 – 2010-01-14 16:40:55

相關問題