Навигация по иерархии данных с табличными представлениями
Общее использование табличных представлений — и одно, к которому они идеально подходят — должны переместиться по иерархиям данных. Табличное представление на верхнем уровне иерархии перечисляет категории данных на наиболее общем уровне. Пользователи выбирают строку для «выполнения развертку» к следующему уровню в иерархии. У основания иерархии представление (часто табличное представление), который представляет подробные данные о конкретном изделии (например, запись адресной книги) и может позволить пользователям редактировать элемент. Этот раздел объясняет, как Вы можете отобразить уровни иерархии модели данных к преемственности табличных представлений и описываете, как можно использовать средства платформы UIKit, чтобы помочь Вам реализовать такие основанные на навигации приложения.
Иерархические модели данных и табличные представления
Для основанного на навигации приложения Вы обычно разрабатываете свои данные приложения как график объектов модели, иногда упоминающийся как модель данных приложения. Можно тогда реализовать уровень модели приложения с помощью различных механизмов или технологий, включив Базовые Данные, списки свойств или архивы пользовательских объектов. Независимо от подхода обход модели данных Вашего приложения следует за образцами, которые характерны для всех основанных на навигации приложений. Модель данных имеет иерархическую глубину и возражает на различных уровнях этой иерархии, должен быть источник для заполнения строк табличного представления.
Модель данных как иерархия объектов модели
Хорошо разработанные факторы приложения его классы и объекты в пути, соответствующем шаблону разработки Model-View-Controller (MVC). Модель данных приложения состоит из объектов модели в этом образце. Можно описать объекты модели (использующий терминологию, предоставленную образцом объектного моделирования) с точки зрения их свойств. Эти свойства являются двумя общими видами: атрибуты и отношения.
Атрибуты представляют элементы данных объекта модели. Атрибуты могут колебаться от экземпляра примитивного класса (например, NSString
, NSDate
, или UIColor
объект) к структуре C или простому скалярному значению. Атрибуты обычно, что Вы используете для заполнения табличного представления, представляющего «вершину» иерархии данных, и это представляет подробное представление того элемента.
Объект модели может также иметь отношения с другими объектами модели. Именно через эти отношения модель данных получает иерархическую глубину путем создания графа объектов. Отношения являются двумя общими видами с точки зрения кардинальности: к - один и к - многие. К - отношения определяют отношение объекта с помощью другого объекта (например, родительское отношение). К - многие отношение, с другой стороны, определяет отношение объекта с помощью многократных объектов того же вида. К - многие отношение характеризуется включением и может быть программно представлено наборами такой как NSArray
объекты (или, просто, массивы). Массив мог бы содержать другие массивы, или он мог содержать многократные словари, которые являются наборами, идентифицирующими их содержавшие значения через ключи. Словари, в свою очередь, может содержать один или несколько других наборов, включая массивы, наборы, и даже другие словари. Как вложенное множество наборов в других наборах, Ваша модель данных может получить иерархическую глубину.
Табличные представления и модель данных
Строки простого табличного представления обычно поддерживаются объектами коллекции модели данных приложения; эти объекты обычно являются массивами. Массивы содержат строки или другие элементы, которые табличное представление может использовать при отображении содержания строки. При создании табличного представления (описанный в Создании и Конфигурировании Табличного представления), это сразу запрашивает свой источник данных для его размерностей — т.е. это запрашивает число разделов и число строк на раздел — и затем просит содержание каждой строки. Источник данных выбирает это содержание от массива на надлежащем уровне иерархии модели данных.
Во многих методах, определенных для источника данных и делегата табличного представления, табличное представление передает по индексному пути для идентификации раздела и строки, которая является фокусом текущей работы — например, выбирающее содержание для строки или указания строки, которой коснулся пользователь. Индексный путь является экземпляром платформы Основы NSIndexPath
класс, который можно использовать для идентификации элемента в дереве вложенных массивов. Платформа UIKit расширяется NSIndexPath
добавить a section
и a строка
свойство к классу. Источник данных должен использовать эти свойства для отображения раздела и строки табличного представления к значению в соответствующем индексе массива, используемого в качестве источника табличного представления данных.
В последовательности табличных представлений на рисунке 3-1 верхний уровень иерархии данных является массивом четырех массивов с каждым внутренним массивом, содержащим объекты, представляющие следы для определенной области. Когда пользователь выбирает одну из этих областей, следующие имена списков табличного представления, идентифицирующие следы в выбранном массиве. Когда пользователь выбирает определенный след, следующее табличное представление описывает тот след с помощью сгруппированного табличного представления.
Контроллеры представления и основанные на навигации приложения
Платформа UIKit обеспечивает много классов контроллера представления для управления образцами общего пользовательского интерфейса в iOS. Контроллеры представления являются объектами контроллера, наследовавшимися от UIViewController
класс. Когда приложение использует те представления для представления последовательных уровней его иерархии данных, они - существенный инструмент для управления представлением, особенно. В этом разделе описываются как два подкласса UIViewController
, контроллеры навигации и контроллеры табличного представления, представьте и управляйте преемственностью табличных представлений.
Контроллеры навигации
UINavigationController
класс наследовался от UIViewController
, базовый класс, определяющий общий программируемый интерфейс и поведение для объектов контроллера, управляющих представлениями в iOS. Посредством наследования от этого базового класса контроллер представления получает интерфейс для управления общим мнением. После того, как это реализует части этого интерфейса, контроллер представления может самовращаться свое представление, реагировать на уведомления низкой памяти, наложить «модальные» представления, реагировать на касания на кнопке Edit, и иначе управлять представлением.
Контроллер навигации поддерживает штабель контроллеров представления, один для каждого из выведенных на экран табличных представлений (см. рисунок 3-2). Это начинается с того, что известно как корневой контроллер представления. Когда пользователь касается строки табличного представления (часто на подробной кнопке раскрытия), корневой контроллер представления продвигает следующий контроллер представления на штабель. Новое табличное представление контроллера представления визуально скользит в место от права, и элементы панели навигации обновляются соответственно. Когда пользователи касаются кнопки «Назад» в панели навигации, контроллер текущего представления выталкивается от штабеля. Как следствие контроллер навигации выводит на экран табличное представление, которым управляет контроллер представления, который является теперь наверху штабеля.
Панели навигации
Панели навигации являются устройством пользовательского интерфейса, позволяющим пользователям переместиться по иерархии данных. Пользователи запускают с общих, элементов верхнего уровня и «выполняют развертку» иерархии к подробным представлениям, показывающим определенные свойства элементов вершины. Представление ниже панели навигации представляет текущий уровень данных. Если то представление ниже в иерархии, чем верхний уровень, кнопка «Назад» на левой стороне панели, панель навигации включает заголовок для текущего представления и; кнопка «Назад» является управлением навигацией, которого пользователь касается для возврата к предыдущему уровню. (Кнопка «Назад» значением по умолчанию выводит на экран заголовок для предыдущего представления.) Панель навигации может также иметь кнопку Edit — раньше вводил режим редактирования для текущего представления — или пользовательские кнопки для функций, управляющих содержанием (см. рисунок 3-3).
A UINavigationController
управляет баром навигации, включая элементы, выведенные на экран в панели для представления ниже его. A UIViewController
объект управляет представлением, выведенным на экран ниже панели навигации. Для этого контроллера представления Вы создаете подкласс UIViewController
или подкласс класса контроллера представления, что платформа UIKit предусматривает управление определенным типом представления. Для табличных представлений этот класс контроллера представления UITableViewController
. Для контроллера навигации, выводящего на экран последовательность табличных представлений, отражающих уровни в иерархии данных, необходимо создать отдельный пользовательский контроллер табличного представления для каждого табличного представления.
UIViewController
класс включает методы, позволяющие доступу контроллеров представления и устанавливающие элементы навигации, выведенные на экран в панели навигации для в настоящее время выводимого на экран табличного представления. Этот класс также объявляет a заголовок
свойство через который можно установить заголовок панели навигации для текущего табличного представления.
Контроллеры табличного представления
Несмотря на то, что Вы могли управлять табличным представлением с помощью прямого подкласса UIViewController
, если вместо этого Вы разделяете на подклассы, Вы спасаете себя большая работа UITableViewController
. UITableViewController
класс заботится о многих подробных данных, которые необходимо было бы реализовать при создании прямого подкласса UIViewController
управлять табличным представлением.
Рекомендуемый способ создать контроллер табличного представления состоит в том, чтобы указать его в раскадровке. Связанное табличное представление загружается из раскадровки, вместе с атрибутами табличного представления, размером и характеристиками автоизменения размеров. Контроллер табличного представления устанавливает себя как источник данных и делегат табличного представления.
Когда табличное представление собирается появиться впервые, контроллер табличного представления отправляет reloadData
к табличному представлению, запрашивающему его запрашивать данные от своего источника данных. Источник данных говорит табличное представление, сколько разделов и строк на раздел это хочет, и затем дает табличному представлению данные для отображения в каждой строке. Этот процесс описан в Создании и Конфигурировании Табличного представления.
UITableViewController
класс также выполняет другие общие задачи. Это очищает выборы, когда табличное представление собирается быть выведенным на экран и высвечивает индикаторы прокрутки, когда таблица заканчивает показывать. Кроме того, это отвечает должным образом, когда пользователи касаются кнопки Edit путем помещения табличного представления в режим редактирования (или вынимая его из режима редактирования, если пользователи касаются Сделанный). Класс представляет одно свойство, tableView
, который предоставляет Вам доступ к управляемому табличному представлению.
UITableViewController
класс реализует предшествующее поведение путем переопределения loadView
, viewWillAppear:
, и другие методы наследовались от UIViewController
. В Вашем подклассе UITableViewController
, можно также переопределить эти методы для получения специализированного поведения. Если Вы действительно переопределяете эти методы, несомненно, вызовут реализацию суперкласса метода, обычно как первый вызов метода, получат поведение по умолчанию.
Управление табличными представлениями в основанном на навигации приложении
A UITableViewController
объект — или любой другой объект, принимающий роли источника данных и делегата к табличному представлению — должен реагировать на сообщения, отправленные табличным представлением, чтобы заполнить его строки, сконфигурировать его, реагируйте на выборы и управляйте сеансами редактирования. В остальной части этого документа Вы изучаете, как сделать эти вещи. Однако существуют определенные другие вещи, которые необходимо сделать для обеспечения надлежащего дисплея последовательности табличных представлений в основанном на навигации приложении.
В этой точке давайте предположим, что табличное представление, которым управляет контроллер табличного представления, представляет список пользователю. Как делает отображение приложения следующее табличное представление в последовательности?
Когда пользователь касается строки табличного представления, табличное представление вызывает tableView:didSelectRowAtIndexPath:
или tableView:accessoryButtonTappedForRowWithIndexPath:
метод реализован делегатом. (Что последний метод вызывается, если пользователь касается подробной кнопки раскрытия строки.) Делегат создает контроллер табличного представления, управляющий следующим табличным представлением в последовательности, устанавливает данные, это должно заполнить свое табличное представление и продвигает этот новый контроллер представления на штабель контроллера навигации контроллеров представления. Раскадровка обеспечивает спецификацию, позволяющую UIKit выполнять большую часть этой работы для Вас.
Раскадровки представляют экраны в приложении и переходах между ними. Раскадровка в основном приложении может содержать всего несколько экранов, но более сложное приложение могло бы иметь многократные раскадровки, каждая из которых представляет различное подмножество своих экранов. Пример раскадровки на рисунке 3-4 представляет графическое представление каждой сцены, ее содержания и ее соединений.
Сцена представляет экранную предметную область, которой управляет контроллер представления. (В контексте раскадровки сцена и контроллер представления являются синонимичными терминами.) Крайняя левая сцена в раскадровке по умолчанию представляет контроллер навигации. Контроллер навигации является контейнерным контроллером представления, потому что в дополнение к его представлениям он также управляет рядом других контроллеров представления. Например, контроллер навигации на рисунке 3-4 управляет ведущим устройством и подробными контроллерами представления, в дополнение к панели навигации и кнопке «Назад», которую Вы видите при выполнении приложения.
Отношение является типом соединения между сценами. На рисунке 3-4 существует отношение между контроллером навигации и основной сценой. В этом случае отношение представляет включение ведущего устройства и подробных сцен контроллером навигации. Когда выполнение приложения, контроллер навигации автоматически загружает основную сцену и выводит на экран панель навигации наверху экрана.
Переход представляет переход от одной сцены (названный источником) к следующей сцене (названный местом назначения). Например, на рисунке 3-4, основная сцена является источником, и подробная сцена является местом назначения. При выборе Подробного элемента в основном списке Вы инициировали переход от источника до места назначения. В этом случае переход является переходом нажатия, что означает, что целевая сцена скользит по исходной сцене справа налево. Поскольку подробный экран показан, кнопка «Назад» появляется в левом конце панели навигации, названной с заголовком предыдущего экрана (в этом случае, «Ведущее устройство»). Кнопка «Назад» предоставлена автоматически контроллером навигации, управляющим иерархией основной подробности.
Раскадровки упрощают передавать данные от одной сцены до другого через prepareForSegue:sender:
метод UIViewController
класс. Когда первая сцена (источник) собирается переход к следующей сцене (место назначения), этот метод вызывают. Исходный контроллер представления может реализовать prepareForSegue:sender:
выполнять задачи установки, такие как передающая информация к целевому контроллеру представления о том, что это должно вывести на экран в его табличном представлении. Перечисление 3-1 показывает одну реализацию этого метода.
Перечисление 3-1 Передающие данные к целевому контроллеру представления
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender |
{ |
if ([[segue identifier] isEqualToString:@"ShowDetails"]) { |
MyDetailViewController *detailViewController = [segue destinationViewController]; |
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow]; |
detailViewController.data = [self.dataController objectInListAtIndex:indexPath.row]; |
} |
} |
Переход представляет односторонний переход от исходной сцены до целевой сцены. Одно из последствий этого проекта - то, что можно использовать переход, чтобы передать данные месту назначения, но Вы не можете использовать переход для отправки данных от места назначения к его источнику. Для решения этой проблемы Вы создаете протокол делегата, объявляющий методы, которые вызывает целевой контроллер представления, когда это должно пасовать назад некоторые данные.
Перечисление 3-2 показывает одну реализацию протокола для того, чтобы пасовать назад данные к исходному контроллеру представления.
Перечисление 3-2 Передающие данные к источнику просматривает контроллер
@protocol MyAddViewControllerDelegate <NSObject> |
- (void)addViewControllerDidCancel:(MyAddViewController *)controller; |
- (void)addViewControllerDidFinish:(MyAddViewController *)controller data:(NSString *)item; |
@end |
- (void)addViewControllerDidCancel:(MyAddViewController *)controller { |
[self dismissViewControllerAnimated:YES completion:NULL]; |
} |
- (void)addViewControllerDidFinish:(MyAddViewController *)controller data:(NSString *)item { |
if ([item length]) { |
[self.dataController addData:item]; |
[[self tableView] reloadData]; |
} |
[self dismissViewControllerAnimated:YES completion:NULL]; |
} |
Шаблон разработки для основанных на навигации приложений
Основанное на навигации приложение с табличными представлениями должно следовать за этими методами наиболее успешной практики проекта:
Контроллер представления (обычно подкласс
UITableViewController
), при действии в роли источника данных, заполняет его табличное представление с данными от объекта, представляющего уровень иерархии данных.Когда табличное представление выводит на экран список элементов, объект обычно является массивом. Когда табличное представление выводит на экран подробность элемента (т.е. вершина иерархии данных), объект может быть пользовательским объектом модели, Базовым управляемым объектом Данных, словарем или чем-то подобным.
Контроллер представления хранит данные, в которых он нуждается для заполнения его табличного представления.
Контроллер представления может использовать эти данные непосредственно для заполнения табличного представления, или это может использовать его, чтобы выбрать или иначе получить необходимые данные. При разработке подкласса контроллера представления необходимо определить свойство для содержания этих данных.
Контроллеры представления не должны получать данные для своего табличного представления через глобальную переменную или одноэлементный объект, такой как делегат приложения. Такие прямые зависимости делают Ваш код менее допускающим повторное использование и более трудным протестировать и отладить.
Контроллер текущего представления поверх штабеля контроллера навигации создает следующий контроллер представления в последовательности и, прежде чем это продвинет его на штабель, устанавливает данные, что этот контроллер представления, действуя как источник данных, должен заполнить свое табличное представление.