Способный переупорядочиванием UITableView с Max # строк на раздел

Я плохо знаком с iPhone dev и программирующий в целом, недавно завершив Программирование Stephen Kochan в Objective C 2.0, и части iPhone Cookbook Erica Sadun. Просто чтение вопросов, на которые отвечают, на этом сайте помогло мне много, таким образом, я должен большое спасибо всем его пользователям. Теперь я работаю над своим первым приложением для iPhone, и добиваюсь существенного прогресса, сохраняю, с одной стороны, этому озадачили меня.

Я испытываю некоторые затруднения из-за UITableView. В основном у меня есть таблица, которая должна иметь максимум 6 строк на раздел без минимума (кроме того, если строка раздела с 1 строкой удалена, в этом случае раздел соглашается с ним). Таблица может также быть переупорядочена пользователем. Когда пользователь перетаскивает строку в раздел, который уже имеет максимальные 6 выделенных строк, я хочу нижний ряд того раздела к виду - 'сдвигаются с места' вниз для становления верхним рядом следующего раздела.

Что касается реализации этого, моя первая мысль состояла в том, чтобы призвать метод tableView:moveRowAtIndexPath:toIndexPath: это прошло бы разделы в цикле, удостоверившись, что ни один из них не имел 7 + строки, корректируя массив по мере необходимости, и затем с помощью a [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 методы, включая targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath:, и несколько таинственное willMoveToRowAtIndexPath:fromIndexPath: метод, который упоминается в руководстве Apple по TableViews, но не существует в другом месте.

Я искал на всем протяжении Google, этого сайта и документов Apple для любого подозрения решения, но напрасно.

Так, для помещения моего вопроса просто, что лучший способ состоит в том, чтобы пойти об этом? Есть ли некоторая очевидная вещь, которую я пропускаю? Или мое понятие реализации просто существенно испорчено с самого начала?

Заранее спасибо за справку! Любое понимание очень ценилось бы.

- Drew R. Капот

ОБНОВЛЕНИЕ: Следуя совету Иордании из его комментария к его ответу, я проверил, что фактические редактирования к источнику данных проходят правильно. Я теперь последовательно получаю ошибку Attempt to create two animations for cell когда блок редактирования таблицы выполняется (что, синхронизируя проверенный здравым смыслом и точками останова). Таким образом, я делаю что-то не так в своем блоке редактирования. Текущий код для этого точно как показано выше. Идеи?

6
задан LOZ 14 August 2012 в 14:40
поделиться

2 ответа

Итак, я наконец-то решил проблему и подумал, что опубликую то, что я сделал здесь ради потомства. Это довольно просто, правда: я только что переместил фактическую вставку и удаление строк в таблицу в отдельный метод, который я тогда вызываю после задержки. С самого начала было ясно, и Джордан помог мне подтвердить, что проблема возникла при выполнении обновлений самой таблицы, а не в процессе фактически меняющихся данных. Итак, вот код, который сделал трюк:

-(void) performBudges
{
if ( PM_DEBUG_MODE )
    NSLog(@"Performing budge animations...");

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

[editTable performSelector: @selector(reloadData) withObject: nil afterDelay: 0.5];

[reloadedSections release];

[budgeFrom release];
[budgeTo release];

if ( PM_DEBUG_MODE )
    NSLog(@"Budges completed!");
} 

и все, что я должен сделать, чтобы выполнить это, это добавить этот фрагмент в мою MOUROWATINDEXPATH: Метод:

if ( [[PET_ICON_DATA objectAtIndex: to.section] count] > 6 ) {

    [self budgeRowsAtSection: to.section];
    [self performSelector: @selector(performBudges) withObject: nil afterDelay: 1.0];

}

Так что я надеюсь, что это поможет всем, кто может иметь это проблема в будущем. Благодаря Иорданию и всем, кто рассматривал этот вопрос. :)

0
ответ дан 17 December 2019 в 20:32
поделиться

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

Я считаю, что вам нужно обновить DataSource, прежде чем вы действительно удалите строку в том разделе, из которого вы ее удаляете. Итак, в этом коде, прежде чем выполнять удаление, удалите строку из Table_Array_Macro (где, как мне кажется, находятся ваши данные).

2
ответ дан 17 December 2019 в 20:32
поделиться