- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
iOS. Приемы программирования - Вандад Нахавандипур
Шрифт:
Интервал:
Закладка:
• вручную инстанцировав класс UITableView.
Оба этих метода вполне допустимы для создания табличных видов. Первый метод обычно используется для создания табличного вида, который целиком заполняет свой контейнер (либо окно/экран, если данный контроллер вида является корневым контроллером вида основного окна приложения). Второй метод более удобен в ситуациях, когда вы собираетесь отобразить табличный вид в качестве небольшого компонента пользовательского интерфейса, чтобы таблица, скажем, наполовину занимала экран по ширине и/или высоте. Но вы с тем же успехом можете использовать второй метод для установки высоты и ширины табличного вида в значения высоты и ширины его объемлющего окна так, чтобы табличный вид занимал целый экран. В этой главе мы исследуем оба описанных метода.
Рассмотрим пример создания табличного вида в приложении. Примеры контроллеров табличных видов будут подробно изучены в разделе 4.9, а пока мы просто займемся созданием таких видов в коде и будем добавлять их к имеющемуся контроллеру вида.
Класс UITableView инстанцируется с помощью метода initWithFrame: style:. Далее перечислены параметры, которые мы должны передать этому методу, а также значения этих параметров.
• initWithFrame — это параметр типа CGRect. Он указывает, как именно должен быть расположен табличный вид в вышестоящем виде. Если вы хотите, чтобы таблица просто полностью накрывала вышестоящий вид, передайте этому параметру значение свойства bounds вида с контроллером.
• style — это параметр типа UITableViewStyle, определяемый следующим образом:
typedef NS_ENUM(NSInteger, UITableViewStyle) {
UITableViewStylePlain,
UITableViewStyleGrouped
};
На рис. 4.1 показана разница между обычным и сгруппированным табличными видами.
Рис. 4.1. Табличные виды различных типов
Мы заполняем табличный вид информацией, используя его источник данных, как будет показано в разделе 4.1. Табличные виды также обладают делегатами. Делегаты получают различные события от табличного вида. Объекты делегатов должны соответствовать протоколу UITableViewDelegate. Далее перечислены отдельные методы этого протокола, которые необходимо знать.
• tableView: viewForHeaderInSection: — вызывается в делегате, когда табличному виду требуется отобразить заголовочный вид раздела. Каждый раздел табличного вида может содержать верхний колонтитул, некоторое количество ячеек и нижний колонтитул. В этой главе мы подробно обсудим все эти участки таблицы. Верхний и нижний колонтитул — это обычные экземпляры UIView. Данный метод является необязательным, но если вы хотите сконфигурировать заголовок для разделов вашего табличного вида, то пользуйтесь этим методом, чтобы создать экземпляр вида и передать его обратно в качестве возвращаемого значения. О верхних и нижних колонтитулах табличных видов подробнее рассказано в разделе 4.5.
• tableView: viewForFooterInSection: — делегатный метод, аналогичный tableView: viewForHeaderInSection:, но он возвращает вид с нижним колонтитулом таблицы. Как и заголовок, нижний колонтитул таблицы не является обязательным, но если он вам нужен, то его следует создавать здесь. Подробнее о верхних и нижних колонтитулах табличных видов рассказано в разделе 4.5.
• tableView: didEndDisplayingCell: forRowAtIndexPath: — вызывается в объекте-делегате, когда в ходе прокрутки таблицы ячейка уходит с экрана. Этот метод действительно очень удобен для вызова в делегате, так как вы можете удалять объекты и выбрасывать их из памяти, если эти объекты ассоциированы с ячейкой, которая ушла с экрана, а вы полагаете, что связанные с ней объекты вам больше не понадобятся.
• tableView: willDisplayCell: forRowAtIndexPath: — этот метод вызывается в делегате табличного вида всякий раз, когда ячейка вот-вот отобразится на экране.
Чтобы задать делегат для табличного вида, просто укажите в качестве значения свойства delegate экземпляра UITableView такой объект, который соответствует протоколу UITableViewDelegate. Если табличный вид является частью контроллера вида, то можно просто сделать этот контроллер делегатом вашего табличного вида, вот так:
#import «ViewController.h»
@interface ViewController () <UITableViewDelegate>
@property (nonatomic, strong) UITableView *myTableView;
@end
@implementation ViewController
— (void)viewDidLoad{
[super viewDidLoad];
self.myTableView = [[UITableView alloc]
initWithFrame: self.view.bounds
style: UITableViewStylePlain];
self.myTableView.delegate = self;
[self.view addSubview: self.myTableView];
}
@end
Можно считать делегат табличного вида объектом, который слушает различные события, отправляемые табличным видом. Например, такие события происходят, когда пользователь выделяет одну из ячеек в таблице либо табличному виду требуется узнать высоту всех входящих в него ячеек.
Объект-делегат обязан отвечать на сообщения, помеченные протоколом UITableViewDelegate как @required. Отвечать на другие сообщения не обязательно, но делегат должен отвечать на все сообщения, которые, по вашему замыслу, будут изменять табличный вид.
Сообщения, отправляемые объекту-делегату табличного вида, несут с собой параметр, который сообщает делегату, какой именно табличный вид инициировал данное событие в своем делегате. Это очень важно отметить, так как в определенных обстоятельствах вы можете разместить в одном объекте (как правило, в виде) более одной таблицы. Поэтому настоятельно рекомендую принимать соответствующие решения с учетом того, какой именно табличный вид послал конкретное сообщение объекту-делегату:
— (CGFloat) tableView:(UITableView *)tableView
heightForRowAtIndexPath:(NSIndexPath *)indexPath{
if ([tableView isEqual: self.myTableView]){
return 100.0f;
}
return 40.0f;
}
}
Расположение ячейки в табличном виде представляется индексным путем этой ячейки. Индексный путь — это комбинация данных о разделе и индекса строки. В данном случае индекс раздела имеет нулевую базу и указывает, к каким группе или разделу относится каждая ячейка. Индекс ячейки также имеет нулевую базу и означает положение данной ячейки в ее разделе.
4.1. Наполнение табличного вида данными
Постановка задачи
Требуется наполнить табличный вид данными.
Решение
Необходимо создать объект, соответствующий протоколу 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 программистам приходилось инстанцировать эти ячейки самостоятельно, если из табличного вида не удавалось добыть уже готовый код, пригодный для повторного использования.

