Вставка и удаление строк и разделов

Табличное представление имеет режим редактирования, а также его нормальное (выбор) режим. Когда табличное представление входит в режим редактирования, оно выводит на экран редактирование и переупорядочение средств управления, связанных с его строками. Средства управления редактированием, которые находятся в левой стороне строки, позволяют пользователю вставлять и удалять строки в табличном представлении. Средства управления редактированием имеют отличительные появления:

deletion control

Управление удалением

insertion control

Управление вставкой

Когда табличное представление вводит режим редактирования и когда пользователи щелкают по управлению редактированием, табличное представление отправляет ряд сообщений к его источнику данных и делегату, но только если они реализуют эти методы. Эти методы позволяют источнику данных и делегату совершенствовать появление и поведение строк в табличном представлении; сообщения также позволяют им выполнить работа вставки или удаление.

Даже если табличное представление не находится в режиме редактирования, можно вставить или удалить много строк или разделов как группа и перенести те анимированные операции.

Первый раздел ниже шоу Вы, как, когда таблица находится в режиме редактирования, чтобы вставить новые строки и удалить существующие строки в табличном представлении в ответ на пользовательские действия. Второй раздел, Пакетная Вставка, Удаление, и Перезагрузка строк и Разделов, обсуждает, как можно вставить и удалить многократные разделы и строки, анимированные как группа.

Вставка и удаление строк в режиме редактирования

Когда Редактируется Табличное представление

Табличное представление входит в режим редактирования, когда это получает a setEditing:animated: сообщение. Когда пользователь касается кнопки Edit в панели навигации, обычно (но не обязательно) сообщение происходит как сообщение действия, отправленное. В режиме редактирования табличное представление выводит на экран любое редактирование (и переупорядочение) средства управления, которые его делегат присвоил каждой строке. Делегат присваивает средства управления в результате возврата стиля редактирования для строки в tableView:editingStyleForRowAtIndexPath: метод.

Когда табличное представление получает setEditing:animated:, это отправляет то же сообщение в UITableViewCell объект для каждой видимой строки. Тогда это отправляет преемственность сообщений к ее источнику данных и ее делегату (если они реализуют методы), как изображено в схеме на рисунке 7-1.

  Вызывающая последовательность рисунка 7-1 для вставки или удаления строк в табличном представлении
Calling sequence for inserting or deleting rows in a table view

После повторной отправки setEditing:animated: к ячейкам, соответствующим видимым строкам, последовательность сообщений следующие:

  1. Табличное представление вызывает tableView:canEditRowAtIndexPath: метод, если его источник данных реализует его. Этот метод позволяет приложению исключать строки в табличном представлении от того, чтобы быть отредактированным даже когда их ячейка editingStyle свойство указывает иначе. Большинство приложений не должно реализовывать этот метод.

  2. Табличное представление вызывает tableView:editingStyleForRowAtIndexPath: метод, если его делегат реализует его. Этот метод позволяет приложению указывать стиль редактирования строки и таким образом управление редактированием, которое выводит на экран строка.

    В этой точке табличное представление находится полностью в режиме редактирования. Это выводит на экран вставку или управление удалением для каждой приемлемой строки.

  3. Пользователь касается управления редактированием (или управление удалением или управление вставкой). Если он или она касается управления удалением, кнопка Delete выведена на экран на строке. Пользователь тогда касается той кнопки для подтверждения удаления.

  4. Табличное представление отправляет tableView:commitEditingStyle:forRowAtIndexPath: обменивайтесь сообщениями к источнику данных. Несмотря на то, что этот метод протокола отмечен как дополнительный, источник данных должен реализовать его, если он хочет вставить или удалить строку. Это должно сделать две вещи:

    • Отправить deleteRowsAtIndexPaths:withRowAnimation: или insertRowsAtIndexPaths:withRowAnimation: к табличному представлению для направления его для корректировки его представления.

    • Обновите соответствующий массив модели данных или удалением элемента, на который ссылаются, от массива или добавлением элемента к массиву.

Когда пользователь сильно ударяет через строку для отображения кнопки Delete для той строки, существует изменение в вызывающей последовательности, схематически изображенной на рисунке 7-1. Когда пользователь сильно ударяет строка для удаления его, табличное представление сначала проверяет, чтобы видеть, реализовал ли его источник данных tableView:commitEditingStyle:forRowAtIndexPath: метод; если это так, это отправляет setEditing:animated: к себе и вводит режим редактирования. В этом “сильно ударяют для удаления” режима, табличное представление не выводит на экран редактирование и переупорядочение средств управления. Поскольку это - управляемое пользователями событие, оно также заключает в скобки сообщения делегату в двух других сообщениях: tableView:willBeginEditingRowAtIndexPath: и tableView:didEndEditingRowAtIndexPath:. Путем реализации этих методов делегат может обновить появление табличного представления соответственно.

Несмотря на то, что можно использовать управление вставкой в качестве триггера для вставки новой строки в табличное представление, альтернативный подход должен иметь Добавление (или знак «плюс») кнопка в панели навигации. Ответвление кнопки отправляет сообщение действия в контроллер представления, накладывающий табличное представление с модальным представлением для ввода нового элемента. Как только элемент вводится, контроллер добавляет его к массиву модели данных и перезагружает таблицу. Пример Добавления строки Табличного представления обсуждает этот подход.

Пример удаления строки табличного представления

В этом разделе приведены экскурсию через части проекта, сотрудничающие, чтобы установить табличное представление для режима редактирования и удалить строки из него. Этот проект использует контроллер навигации и архитектуру контроллера представления для управления ее табличными представлениями. В loadView метод, пользовательский контроллер представления создает табличное представление и устанавливает себя, чтобы быть источником данных и делегатом. Это также устанавливает правильный элемент панели навигации, чтобы быть стандартной кнопкой Edit.

self.navigationItem.rightBarButtonItem = self.editButtonItem;

Эта кнопка предварительно сконфигурирована для отправки setEditing:animated: к контроллеру представления, когда коснулись; это переключает заголовок кнопки (между Редактированием и Сделанный) и параметр редактирования булевской переменной при чередовании касаний. В его реализации метода, как показано в Перечислении 7-1, контроллер представления вызывает вызов суперкласса метода, отправляет то же сообщение в табличное представление и обновляет включенное состояние другой кнопки в панели навигации (кнопка знака «плюс» для добавления элементов).

  Контроллер Представления перечисления 7-1, отвечающий на setEditing:animated:

- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
    [super setEditing:editing animated:animated];
    [tableView setEditing:editing animated:YES];
    if (editing) {
        addButton.enabled = NO;
    } else {
        addButton.enabled = YES;
    }
}

Когда его табличное представление вводит режим редактирования, контроллер представления указывает управление удалением для каждой строки кроме последнего, имеющего контроль вставкой. Это делает это в своей реализации tableView:editingStyleForRowAtIndexPath: метод (Перечисление 7-2).

Перечисление 7-2  Настраивая стиль редактирования строк

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
    SimpleEditableListAppDelegate *controller = (SimpleEditableListAppDelegate *)[[UIApplication sharedApplication] delegate];
    if (indexPath.row == [controller countOfList]-1) {
        return UITableViewCellEditingStyleInsert;
    } else {
        return UITableViewCellEditingStyleDelete;
    }
}

Пользователь касается управления удалением подряд, и контроллер представления получает a tableView:commitEditingStyle:forRowAtIndexPath: сообщение от табличного представления. Как показано в Перечислении 7-3, это обрабатывает это сообщение путем удаления элемента, соответствующего строке от массива модели и отправки deleteRowsAtIndexPaths:withRowAnimation: к табличному представлению.

Перечисление 7-3  , Обновляющее массив модели данных и удаляющее строку

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    // If row is deleted, remove it from the list.
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        SimpleEditableListAppDelegate *controller = (SimpleEditableListAppDelegate *)[[UIApplication sharedApplication] delegate];
        [controller removeObjectFromListAtIndex:indexPath.row];
        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
    }
}

Пример добавления строки табличного представления

Этот раздел показывает код проекта, вставляющий строку в табличное представление. Вместо того, чтобы использовать управление вставкой в качестве триггера для вставки строки, это использует кнопку Add (визуально знак «плюс») в панели навигации выше табличного представления. Этот код также основывается на контроллере навигации и архитектуре контроллера представления. В loadView реализация метода, контроллер представления присваивает кнопку Add как элемент правой стороны панели навигации с помощью кода, показанного в Перечислении 7-4.

Перечисление 7-4  , Добавляющее кнопку Add к панели навигации

    addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addItem:)];
    self.navigationItem.rightBarButtonItem = addButton;

Обратите внимание на то, что контроллер представления устанавливает состояния управления для заголовка, а также селектора действия и целевого объекта. Когда пользователь касается кнопки Add, addItem: сообщение отправляется в цель (контроллер представления). Это отвечает как показано в Перечислении 7-5. Это создает контроллер навигации с единственным контроллером представления, представление которого помещается на экране модально — это анимирует вверх для накладывания табличного представления. presentModalViewController:animated: метод, чтобы сделать это.

Перечисление 7-5  , Отвечающее на касание на кнопке Add

- (void)addItem:sender {
    if (itemInputController == nil) {
        itemInputController = [[ItemInputController alloc] init];
    }
    UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:itemInputController];
    [[self navigationController] presentModalViewController:navigationController animated:YES];
}

Модальное, или наложение, представление состоит из единственного поля пользовательского текста. Пользователь вводит текст для нового элемента табличного представления и затем касается кнопки Save. Эта кнопка отправляет a save: сообщение действия к его цели: контроллер представления для модального представления. Как показано в Перечислении 7-6, контроллер представления извлекает строковое значение из текстового поля и обновляет массив модели данных приложения с ним.

Перечисление 7-6  , Добавляющее новый элемент к массиву модели данных

- (void)save:sender {
 
    UITextField *textField = [(EditableTableViewTextField *)[tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]] textField];
 
    SimpleEditableListAppDelegate *controller = (SimpleEditableListAppDelegate *)[[UIApplication sharedApplication] delegate];
    NSString *newItem = textField.text;
    if (newItem != nil) {
            [controller insertObject:newItem inListAtIndex:[controller countOfList]];
    }
    [self dismissModalViewControllerAnimated:YES];
}

После того, как модальное представление отклонено, табличное представление перезагружается, и это теперь отражает добавленный элемент.

Пакетная вставка, удаление и перезагрузка строк и разделов

UITableView класс позволяет Вам вставлять, удалять, и перезагружать группу строк или разделов когда-то, анимируя операции одновременно указанными способами. Эти восемь методов, показанных в Перечислении 7-7, принадлежат пакетной вставке и удалению. Обратите внимание на то, что можно вызвать их вставка и методы удаления за пределами блока анимации (как Вы делаете в методе источника данных tableView:commitEditingStyle:forRowAtIndexPath: как обсуждено во Вставке и Удалении строк в Режиме редактирования).

  Вставка Пакета перечисления 7-7 и методы удаления

- (void)beginUpdates;
- (void)endUpdates;
 
- (void)insertSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation;
- (void)deleteSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation;
- (void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation;
 
- (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation: (UITableViewRowAnimation)animation;
- (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation: (UITableViewRowAnimation)animation;
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;

Для анимации пакетной вставки удаление и перезагрузка строк и разделов, вызывают соответствующие методы в блоке анимации, определенном последовательными вызовами к beginUpdates и endUpdates. Если Вы не вызываете вставку, удаление и методы перезагрузки в этом блоке, строке и разделяете индексы, может быть недопустимым. Вызовы к beginUpdates и endUpdates может быть вложен; все индексы обрабатываются, как будто был только внешний блок обновления.

В конце блока — т.е. после endUpdates возвраты — табличное представление запрашивает свой источник данных и делегата, как обычно, к данным раздела и строке. Таким образом объекты коллекции, поддерживающие табличное представление, должны быть обновлены для отражения новых или удаленных строк или разделов.

Пример пакетных операций вставки и удаления

Чтобы вставить и удалить группу строк и разделов в табличном представлении, сначала подготовьте массив (или массивы), которые являются источником данных для разделов и строк. После того, как строки и разделы удалены и вставлены, получающиеся строки и разделы заполняются от этого хранилища данных.

Затем, вызовите beginUpdates метод, сопровождаемый вызовами insertRowsAtIndexPaths:withRowAnimation:, deleteRowsAtIndexPaths:withRowAnimation:, insertSections:withRowAnimation:, или deleteSections:withRowAnimation:. Завершите блок анимации путем вызова endUpdates. Перечисление 7-8 иллюстрирует эту процедуру.

Перечисление 7-8  , Вставляющее и удаляющее блок строк в табличном представлении

- (IBAction)insertAndDeleteRows:(id)sender {
    // original rows: Arizona, California, Delaware, New Jersey, Washington
 
    [states removeObjectAtIndex:4]; // Washington
    [states removeObjectAtIndex:2]; // Delaware
    [states insertObject:@"Alaska" atIndex:0];
    [states insertObject:@"Georgia" atIndex:3];
    [states insertObject:@"Virginia" atIndex:5];
 
    NSArray *deleteIndexPaths = [NSArray arrayWithObjects:
                                [NSIndexPath indexPathForRow:2 inSection:0],
                                [NSIndexPath indexPathForRow:4 inSection:0],
                                nil];
    NSArray *insertIndexPaths = [NSArray arrayWithObjects:
                                [NSIndexPath indexPathForRow:0 inSection:0],
                                [NSIndexPath indexPathForRow:3 inSection:0],
                                [NSIndexPath indexPathForRow:5 inSection:0],
                                nil];
    UITableView *tv = (UITableView *)self.view;
 
    [tv beginUpdates];
    [tv insertRowsAtIndexPaths:insertIndexPaths withRowAnimation:UITableViewRowAnimationRight];
    [tv deleteRowsAtIndexPaths:deleteIndexPaths withRowAnimation:UITableViewRowAnimationFade];
    [tv endUpdates];
 
    // ending rows: Alaska, Arizona, California, Georgia, New Jersey, Virginia
}

Этот пример удаляет две строки из массива (и их соответствующие строки) и вставляет три строки в массив (вместе с их соответствующими строками). Следующий раздел, Упорядочивание Операций и Индексных Путей, объясняет определенные аспекты строки (или раздел) поведение удаления и вставка.

Упорядочивание операций и индексных путей

Вы, возможно, заметили что-то в коде, показанном в Перечислении 7-8, кажущемся странным. Код вызывает deleteRowsAtIndexPaths:withRowAnimation: метод после того, как это вызывает insertRowsAtIndexPaths:withRowAnimation:. Однако это не порядок в который UITableView завершает операции. Это задерживает любые вставки строк или разделов, пока это не обработало удаления строк или разделов. Табличное представление ведет себя тот же путь с перезагрузкой методов, вызванных в блоке обновления — перезагрузка имеет место относительно индексов строк и разделов, прежде чем будет выполнен блок анимации. Это поведение происходит независимо от упорядочивания вставки, удаления и перезагрузки вызовов метода.

Удаление и операции перезагрузки в блоке анимации указывают, какие строки и разделы в исходной таблице должны быть удалены или перезагружены; вставки указывают, какие строки и разделы должны быть добавлены к получающейся таблице. Индексные пути, используемые для идентификации разделов и строк, следуют за этой моделью. Вставка или удаление элемента в непостоянном массиве, с другой стороны, могут влиять на индекс массива, используемый для последовательной вставки или работы удаления; например, при вставке элемента в определенном индексе индексы всех последующих элементов в массиве постепенно увеличиваются.

Пример полезен здесь. Скажите, что у Вас есть табличное представление с тремя разделами, каждый с тремя строками. Тогда Вы реализуете следующий блок анимации:

  1. Начните обновления.

  2. Удалите строку в индексе 1 раздела в индексе 0.

  3. Удалите раздел в индексе 1.

  4. Вставьте строку в индексе 1 раздела в индексе 1.

  5. Обновления конца.

Рисунок 7-2 иллюстрирует то, что имеет место после того, как блок анимации завершает.

  Удаление рисунка 7-2 раздела и строки и вставки строки
Deletion of section and row and insertion of row