Решение
Решение
Необходимо создать объект, соответствующий протоколу UITableViewDataSource, и присвоить этот объект экземпляру табличного вида. Затем, отвечая на сообщения источника данных, предоставьте информацию для вашего вида. Продолжим данный пример и объявим. h-файл контроллера нашего вида. Позже в коде для этого вида будет создана таблица:
#import «ViewController.h»
static NSString *TableViewCellIdentifier = @"MyCells";
@interface ViewController () <UITableViewDataSource>
@property (nonatomic, strong) UITableView *myTableView;
@end
Экземпляр TableViewCellIdentifier содержит идентификаторы ячеек в виде статической строковой переменной. Как вы вскоре узнаете, каждая ячейка может иметь идентификатор, и это очень помогает при повторном использовании ячеек. Пока считайте эту переменную просто уникальным идентификатором всех ячеек табличного вида — на данном этапе этого достаточно.
В методе viewDidLoad контроллера вида создадим табличный вид и присвоим ему контроллер вида в качестве источника данных:
— (void)viewDidLoad{
[super viewDidLoad];
self.myTableView =
[[UITableView alloc] initWithFrame: self.view.bounds
style: UITableViewStylePlain];
[self.myTableView registerClass: [UITableViewCell class]
forCellReuseIdentifier: TableViewCellIdentifier];
self.myTableView.dataSource = self;
/* Убеждаемся, что табличный вид правильно масштабируется. */
self.myTableView.autoresizingMask =
UIViewAutoresizingFlexibleWidth |
UIViewAutoresizingFlexibleHeight;
[self.view addSubview: self.myTableView];
}
В этом фрагменте кода все элементарно, кроме метода registerClass: forCellReuseIdentifier:, который мы вызываем в экземпляре табличного вида. Что же делает этот метод? Параметр registerClass этого метода просто принимает имя класса, соответствующее типу объекта, который вы хотите загружать в табличном виде при отображении каждой ячейки. Все ячейки внутри табличного вида должны быть прямыми или непрямыми потомками класса UITableViewCell. Сам этот класс предоставляет программистам довольно широкий функционал. Но при желании этот класс можно и расширить — достаточно произвести от него подкласс, добавив к новому классу требуемый функционал. Итак, возвращаемся к параметру registerClass вышеупомянутого метода. Вам потребуется сообщить имя класса ячеек этому параметру, а потом передать идентификатор параметру forCellReuseIdentifier. Вот по какой причине мы ассоциируем классы табличного вида с идентификаторами: когда позже вы заполняете табличный вид данными, можете просто передать тот же самый идентификатор методу dequeueReusableCellWithIdentifier: forIndexPath: табличного вида, после чего приказать табличному виду инстанцировать ячейку таблицы, если в наличии нет ячеек, доступных для повторного использования. Все это просто отлично, так как в предыдущих версиях iOS SDK программистам приходилось инстанцировать эти ячейки самостоятельно, если из табличного вида не удавалось добыть уже готовый код, пригодный для повторного использования.
Теперь необходимо убедиться в том, что наш табличный вид реагирует на методы протокола UITableViewDataSource, помеченные как @required (обязательные). Нажмите на клавиатуре комбинацию клавиш Command+Shift+O, введите в диалоговое окно имя этого протокола, затем нажмите клавишу Enter. В результате вы увидите обязательные методы данного протокола.
Класс UITableView определяет свойство под названием dataSource. Это нетипизированный объект, который должен подчиняться протоколу UITableViewDataSource. Всякий раз, когда табличный вид обновляется и перезагружается с помощью метода reloadData, табличный вид будет вызывать в своем источнике данных различные методы, чтобы получить информацию о тех данных, которыми вы хотите заполнить таблицу. Источник данных табличного вида может реализовывать три важных метода, два из которых являются обязательными для любого источника данных:
• numberOfSectionsInTableView: — позволяет источнику данных информировать табличный вид о количестве разделов, которые должны быть загружены в таблицу;
• tableView: numberOfRowsInSection: — сообщает контроллеру вида, сколько ячеек или строк следует загрузить в каждый раздел. Номер раздела передается источнику данных в параметре numberOfRowsInSection. Реализация этого метода является обязательной для объекта источника данных;
• tableView: cellForRowAtIndexPath: — отвечает за возвращение экземпляров класса UITableViewCell как строк таблицы, которыми должен заполняться табличный вид. Реализация этого метода обязательна для объекта источника данных.
Итак, продолжим и реализуем эти методы в контроллере вида один за другим. Сначала сообщим табличному виду, что мы хотим отобразить три раздела:
— (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
if ([tableView isEqual: self.myTableView]){
return 3;
}
return 0;
}
Далее сообщим табличному виду, сколько строк хотим в нем отобразить для каждого раздела:
— (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section{
if ([tableView isEqual: self.myTableView]){
switch (section){
case 0:{
return 3;
break;
}
case 1:{
return 5;
break;
}
case 2:{
return 8;
break;
}
}
}
return 0;
}
Итак, на данный момент мы приказали табличному виду отобразить три раздела. В первом разделе три строки, во втором — пять, в третьем — восемь. Что дальше? Нужно вернуть табличному виду экземпляры UITableViewCell — тех ячеек, которые мы хотим отобразить в таблице:
— (UITableViewCell *) tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *result = nil;
if ([tableView isEqual: self.myTableView]){
cell = [tableView
dequeueReusableCellWithIdentifier: TableViewCellIdentifier
forIndexPath: indexPath];
cell.textLabel.text = [NSString stringWithFormat:
@"Section %ld, Cell %ld",
(long)indexPath.section,
(long)indexPath.row];
}
return cell;
}
Теперь, если запустить приложение в эмуляторе iPhone, мы увидим результат работы (рис. 4.2).
Рис. 4.2. Обычный табличный вид с тремя разделами
Когда табличный вид перезагружается или обновляется, он запрашивает источник данных через протокол UITableViewDataSource, требуя у источника данных различную информацию. В первую очередь он запросит количество разделов. Каждый раздел должен содержать строки или ячейки.
После того как источник данных укажет количество разделов, табличный вид запросит количество строк, которые должны быть загружены в каждый из разделов. Источник данных получает индекс с нулевой базой для каждого раздела и на базе этого индекса решает, сколько ячеек загрузить в каждый раздел.
Табличный вид, определив количество ячеек в разделах, продолжит запрашивать источник данных о видах — один такой вид соответствует каждой ячейке того или иного раздела. Вы можете выделять экземпляры класса UITableViewCell и возвращать их табличному виду. Разумеется, есть свойства, которые можно задать для каждой ячейки. Это, в частности, заголовок, подзаголовок и цвет ячейки.
Данный текст является ознакомительным фрагментом.