2010-01-13 165 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

相关问题