我是iPhone开发人员和编程人员的新手,最近完成了Stephen Kochan的Objective-C 2.0编程,以及部分Erica Sadun的iPhone Cookbook。仅阅读本网站上已回答的问题对我有很大帮助,因此,我要非常感谢它的所有用户。现在,我正在开发自己的第一个iPhone应用程序,并且取得了不错的进展,但有一件事情使我感到困惑。

我在使用UITableView时遇到了一些麻烦。基本上,我有一个表,每个节最多需要有6行,而没有最小值(除非删除了1行节的行,在这种情况下该节也要随之行)。该表也可以由用户重新排序。当用户将一行拖到一个已经有最多6个分配行的节中时,我希望该节的底行进行“预算”排序,成为下一个节的顶行。

至于实现这一点,我的第一个想法是调用tableView:moveRowAtIndexPath:toIndexPath:中的方法,该方法将循环遍历各个节,确保它们中没有一个有7+行,根据需要调整数组,然后使用[myTable beginUpdates]块删除并插入所需的行。这就是所有内容(请注意:我的数组结构是:数组(表)>数组(部分)>词典(项)):

-(void) tableView: (UITableView *) tableView moveRowAtIndexPath: (NSIndexPath *) from toIndexPath: (NSIndexPath *) to
{
// Get the dictionary object for the icon.
NSMutableDictionary *theIcon = [[[TABLE_ARRAY_MACRO objectAtIndex: from.section] objectAtIndex: from.row] mutableCopy];

// Now remove it from the old position, and insert it in the new one.
[[TABLE_ARRAY_MACRO objectAtIndex: from.section] removeObjectAtIndex: from.row];
[[TABLE_ARRAY_MACRO objectAtIndex: to.section] insertObject: theIcon atIndex: to.row];

if ( [[TABLE_ARRAY_MACRO objectAtIndex: to.section] count] > 6 )
          [self budgeRowsAtSection: to.section];

// Now we're done with the dictionary.
[theIcon release];

if ( PM_DEBUG_MODE )
    NSLog(@"Pet moved!");
}



-(void) budgeRowsAtSection: (NSUInteger) section
{
  if ( PM_DEBUG_MODE )
   NSLog(@"Budging rows...");

  // Set up an array to hold the index paths of the cells to move.
  NSMutableArray *budgeFrom = [[NSMutableArray alloc] init];
  NSMutableArray *budgeTo = [[NSMutableArray alloc] init];

  // Start at the current section, and enumerate down to the nearest page with < 6 items.
  int i = section;

 while ( i < [TABLE_ARRAY_MACRO count] ) {

   if ( PM_DEBUG_MODE )
       NSLog(@"Attempting to budge rows in section %i!", i);

   if ( [[TABLE_ARRAY_MACRO objectAtIndex: i] count] > 6 ) {

   // Grab the last object, and move it to the beginning of the next array.
   NSMutableDictionary *lastIcon = [[[PET_ICON_DATA objectAtIndex: i] lastObject] mutableCopy];

   [[TABLE_ARRAY_MACRO objectAtIndex: i] removeLastObject];
   [[TABLE_ARRAY_MACRO objectAtIndex: (i + 1)] insertObject: lastIcon atIndex: 0];

   // Create an index path, and reflect the changes in the table.
   [budgeFrom addObject: [NSIndexPath indexPathForRow: 6 inSection: i]];
   [budgeTo addObject: [NSIndexPath indexPathForRow: 0 inSection: (i + 1)]];

   // Now we're done with the icon.
   [lastIcon release];

 }

 if ( PM_DEBUG_MODE )
      NSLog(@"Rows budged for section %i!", i);

 ++i;

}

  if ( PM_DEBUG_MODE )
    NSLog(@"From cells: %@\nTo cells: %@", budgeFrom, budgeTo);

  if ( PM_DEBUG_MODE )
    NSLog(@"Data budged! Updating table...");

  [editTable beginUpdates];
  [editTable deleteRowsAtIndexPaths: budgeFrom withRowAnimation: UITableViewRowAnimationBottom];
  [editTable insertRowsAtIndexPaths: budgeTo withRowAnimation: UITableViewRowAnimationTop];
  [editTable endUpdates];

  [budgeFrom release];
  [budgeTo release];

  if ( PM_DEBUG_MODE )
   NSLog(@"Row budge done!");
}

问题是,当我运行此命令时,它总是会引发异常。根据我要进行的调整,它会给我Invalid update: number of rows in section after update must be equal to number of rows before update, + or - the number inserted or deleted (etc.)Attempted to create two animations for cell。至于那些调整,我也尝试过使用reloadSections:withRowAnimation:,当然也可以使用简单的[editTable reloadData]。我尝试将对此方法的调用放置在相关的TableView委托(delegate)/数据源方法中,包括targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath:和Apple指南在TableViews中提到的有些神秘的willMoveToRowAtIndexPath:fromIndexPath:方法,但在其他地方则不存在。

我在Google,此站点和Apple的文档中进行了搜索,以寻找解决方案的任何线索,但无济于事。

因此,简单地说,解决此问题的最佳方法是什么?我有什么明显的事情要忽略吗?还是我的实现概念从一开始就存在根本缺陷?

先谢谢您的帮助!任何见解将不胜感激。

-德鲁·胡德(Drew R.Hood)

更新:根据约旦对他的回答的评论的建议,我已经验证了对数据源的实际编辑正在正确进行。现在,在执行表编辑块时,我始终收到错误Attempt to create two animations for cell(该时序由常识和断点验证)。所以我在编辑块中做错了什么。当前的代码与上面的代码完全相同。有想法吗?

最佳答案



我相信您实际上需要在要删除行的任何部分中删除行之前,先更新数据源。因此,在此代码中,执行删除操作之前,请从Table_Array_Macro(我认为这是您的数据所在的位置)中删除该行。

10-07 20:39