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

Воспользуемся исходником из первой части статьи. Для простоты предварительно удалим из него все записи касающиеся массива items2, делегатов titleForHeaderInSection и sectionIndexTitlesForTableView. В navigation bar добавим новую кнопку, нажав на которую мы будем добавлять новую запись в таблицу. Для создания кнопки воспользуемся следующим кодом, который поместим в метод

- (void)viewDidLoad

{
[super viewDidLoad];
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addNew)];
self.navigationItem.leftBarButtonItem = addButton;
[addButton release];
items = [[NSMutableArray alloc] init];
[items addObject:@"Яблоки"];
[items addObject:@"Апельсины"];
[items addObject:@"Груши"];
}

Здесь мы инициализируем новый элемент UIBarButtonItem. Используется метод initWithBarButtonSystemItem, с помощью которого мы можем указываем необходимость создать кнопку со стилем UIBarButtonSystemItemAdd (кнопка с картинкой «+»). После инициализации кнопки мы добавляем ее в navigation bar, указывая что кнопка будет располагаться в левой части. Для каждого нажатия нашей кнопки будет вызываться метод addNew. Перейдем к его определению. В заголовочный файл

- (void) addNew;

В файл имплементации добавим следующий код:

- (void) addNew {

[items addObject:@"Новая запись"];
[tbl reloadData];
}

После каждого вызова метода addNew в массив элементов items будет добавляться новая запись и вызываться метод reloadData для объекта tbl. Но наше приложение еще не знает такого объекта tbl! На самом деле, tbl — это имя нашей таблицы. Перейдем редактор в режим Помощника (Assistant ⌥⌘⏎). В одной половине редактора откроем наш файл с интерфейсом, а во второй — заголовочный файл. Удерживая правую кнопку сделаем перетаскивание элемента интерфейса TableView внутрь заголовочного файла. XCode должен предложить Вам создать outlet. Наберите название tbl и нажмите enter. Теперь связка готова и мы можем обращаться к свойствам и методам элемента TabelView из нашего приложения. Соответственно исходный код, который мы добавили выше будет работать на 100%. Метод reloadData делает перегрузку таблицы. Его необходимо вызывать каждый раз при изменении исходных данных, чтобы табличное представление владело обновленными данными о количестве секций, строк и т.д.

Следующим шагом реализуем удаление элементов из таблицы и массива. Для того, чтобы из нашей таблицы можно было удалять записи, необходимо определить какие ячейки будут редактируемыми. В коде найдем закомментированный делегат canEditRowAtIndexPath и уберем комментарии. По умолчанию делегат возвращает YES для каждой ячейки. Также можно указать только те ячейки, которые будут доступны пользователю для редактирования. Далее найдем еще один закомментированный делегат commitEditingStyle и уберем комментарии с него. Параметрами делегата являются знакомый нам indexPath и editingStyle. editingStyle сообщает какое действие сейчас выполняется над ячейкой. Нас интересуют строки:

if (editingStyle == UITableViewCellEditingStyleDelete)

{
// Delete the row from the data source.
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}

Добавим несколько строк кода:

[items removeObjectAtIndex:indexPath.row];

[tableView beginUpdates];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];

В итоге у нас должен получится следующий код:

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath

{
if (editingStyle == UITableViewCellEditingStyleDelete)
{
// Delete the row from the data source.
[items removeObjectAtIndex:indexPath.row];
[tableView beginUpdates];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
}
else if (editingStyle == UITableViewCellEditingStyleInsert)
{
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
}
}

Первой строкой мы удаляем элемент в массиве items. Удаление ячейки сопровождается анимацией. Этот метод необходимо поместить между beginUpdates и endUpdates. Теперь удалять ячейки можем с помощью привычного жеста слева направо. Также можно добавить кнопку редактировать справой стороны navigation bar. В метод viewDidLoad (там же где мы написали код для кнопки «Добавить») вставим следующий код, который создаст нам кнопку редактирования

self.navigationItem.rightBarButtonItem = self.editButtonItem;

Аналогичным образом раскомментируем делегаты canMoveRowAtIndexPath и moveRowAtIndexPath. Они позволят нам перемещать ячейки внутри таблицы после нажатия кнопки редактирования.

Добавляем поиск в нашу таблицу. Для этого в заголовочном файле запишем две новых переменные:

BOOL searching;

NSMutableArray *search;

Первая логическая переменная будет хранить текущее состояние поиска (идет поиск/или нет). Вторая — это массив найденных элементов. Не забудьте проинициализовать пустой массив и высвободить память. На форму RootViewController.xib добавим новый элемент SearchBar. В свойствах этого элемента отметить галочкой «Show Cancel Button». Нажатие правой кнопкой на добавленном элементе вызовет всплывающее окно. Установите delegate на File’s Owner. Теперь пропишем сами делегаты для поиска:

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {

searching = YES;
[search removeAllObjects];
for (int i=0; i < [items count]; i++) {
NSRange result = [[items objectAtIndex: i] rangeOfString:searchText options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch)];
if (result.location != NSNotFound)
{
[search addObject:[items objectAtIndex:i]];
}
}
[tbl reloadData];
}

Первый делегат вызывается при каждом вводе нового символа в строку поиска. Устанавливаем переменную searching, чтобы отобразить статус поиска (пригодится далее). Далее делаем сравнение введенного текста с каждым элементов массива items. При совпадении — копируем элемент из массива items в массив search. После окончания сравнения делаем перегрузку нашей таблицы.

- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {

[searchBar resignFirstResponder];
searchBar.text=@"";
searching = NO;
[tbl reloadData];
}

Этот делегат будет вызван тогда, когда пользователь нажмет на кнопку «Cancel». Здесь мы скрываем клавиатуру с буквами, устанавливаем переменную поиска, очищаем поле ввода в поисковой панеле и опять делаем перегрузку таблицы. Как Вы можете помнить мы делаем перегрузку таблицы после того, как наши исходные данные изменились. В случае с поиском нам необходимо подменить массивы данных, которые будут выводиться в таблицу. Изменим делегат numberOfRowsInSection в соответствии со следующим кодом:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

{
NSUInteger result;
if (searching) {
result = [search count];
} else {
result = [items count];
}
return result;
}

Здесь мы проверяем состояние логической переменной searching, чтобы понять какое количество ячеек будет в таблице (исходя из того, какой массив будет использоваться). Аналогичным образом добавим код в делегате cellForRowAtIndexPath:

if (searching) {

cell.textLabel.text = [search objectAtIndex:indexPath.row];
cell.detailTextLabel.text = @"Фрукты";
cell.imageView.image = [UIImage imageNamed:@"star_color.png"];
} else {
cell.textLabel.text = [items objectAtIndex:indexPath.row];
cell.detailTextLabel.text = @"Фрукты";
cell.imageView.image = [UIImage imageNamed:@"star_color.png"];
}

Теперь можем запустить наш проект и воспользоваться поиском по таблице.

Еще один важный делегат, с которым часто придется сталкиваться на практике didSelectRowAtIndexPath. Как видно из названия он вызывается каждый раз, когда на ячейке в таблице происходит нажатие. Добавим небольшой код, который будет выводить на экран номер строки в виде сообщения:

NSString *msg = [NSString stringWithFormat:@"Строка %d", indexPath.row];

UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Сообщение" message:msg delegate:self cancelButtonTitle:@"Выйти" otherButtonTitles:nil,nil];
[alertView show];
[alertView release];

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

Продолжение следует… начало тут

Исходники: source-part2

Похожие статьи

  • [Swift] Урок 1 — Пишем программу «Hello, World» на Swift языке под iOS

  • Audio Unit в iOS. Часть 3, накладываем эффект Delay

  • Audio Unit в iOS. Часть 2, строим граф и проигрываем файлы

  • Audio Unit в iOS. Часть 1, введение.

  • Используем Emoji в своих приложениях

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *