Во второй части статьи изучим методы по добавлению и удалению новых элементов в таблице.
Воспользуемся исходником из первой части статьи. Для простоты предварительно удалим из него все записи касающиеся массива 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 в своих приложениях
Сообщить об опечатке
Текст, который будет отправлен нашим редакторам: