uinavigationcontroller ios xcode

Navigation Controllers

Навигационный контроллер управляет стеком контроллеров видов для поддержания интерфейса детализации раскрытия иерархического контента. Видовая иерархия контроллера навигации самодостаточна. Она состоит из видовых представлений, которыми навигационный контроллер управляет непосредственно и видовыми представлениями, которые управляют контентом вами предоставленных контроллеров видов. Каждый контент-контроллер управляет явным видом в иерархии, и контроллер навигации координирует навигацию между этой иерархией видов.

Хотя навигационный интерфейс состоит в основном из пользовательского контента, есть еще места, где ваш код должен взаимодействовать непосредственно с объектом контроллера навигации. В дополнение к сказанному, во время отображения нового вида, вы несете ответственность за настройку навигационного бара в верхней части экрана, который обеспечивает контекст о положении пользователя в навигационной иерархии. Вы также можете предоставить детали для панели инструментов, которая управляется с помощью контроллера навигации.

Анатомия навигационного контроллера

Основной задачей навигационного контроллера является управление презентацией содержимого своего контроллера вида, также он отвечает за представление некоторых собственных пользовательских видовых представлений. В частности, он представляет панель навигации, которая содержит кнопки назад и несколько кнопок, которые можно настроить. Навигационный контроллер может также (необязательно) представить вид с панелью инструментов навигации и заполнить ее пользовательскими кнопками.

Рисунок ниже показывает интерфейс навигации. Вид навигации на этом рисунке является видом хранящемся в свойстве view контроллера навигации. Все остальные виды в интерфейсе являются частью непрозрачной иерархии видов управляемой контроллером навигации.

uinavigationcontroller anatomy

Хотя панель навигации и панель инструментов являются настраиваемыми представлениями видов, вы никогда не должны изменить виды в навигационной иерархии непосредственно. Единственный способ настроить эти виды,- через методы классов UINavigationController и UIViewController.

Объекты навигационного интерфейса

Навигационный контроллер использует несколько объектов для реализации интерфейса навигации. Вы несете ответственность за предоставление некоторых из этих объектов, а остальные, создаются самим контроллером навигации. В частности, вы несете ответственность за предоставление контроллеров видов с контентом. Если вы хотите реагировать на уведомления от контроллера навигации, вы также можете предоставить объект-делегат. Контроллер навигации создает виды,- такие как панель навигации и панель инструментов, которые используются для интерфейса навигации, и отвечает за управление этими видами.

В навигационной панели и панели инструментов объектов, связанных с контроллером навигации, вы можете изменить только некоторые аспекты их внешнего вида и поведения. Только навигационный контроллер отвечает за их настройки и отображение. Кроме того, объект навигационного контроллера автоматически назначает себя в качестве делегата своего UINavigationBar объекта и не позволяет другим объектам измененять это отношение.

Вы можете модифицировать делегата и другие контроллеры видов в стеке навигации. Стек навигации является коллекцией последним вошел, первым вышел пользовательских объектов контроллеров вида, который управляется с помощью контроллера навигации. Первый пункт добавляется в стек, становясь кореневым контроллером вида и никогда не выталкивается из стека. Дополнительные элементы могут быть добавлены в стек с помощью методов класса UINavigationController.

На рисунке ниже показаны соответствующие отношения между контроллером навигации и объектами в стеке навигации. (Обратите внимание, что верхняя контроллер вида (topViewController) и контроллер отображаемого вида (visibleViewController) не обязательно являются одним и темже. Например, если вы представляете контроллер вида модально, значение свойства visibleViewController изменяется чтобы отобразить контроллер вида модально, который был представлен, но свойство topViewController не изменяется.)

uinavigationcontroller stack

Создание навигационного интерфейса

При создании интерфейса навигации, вы должны решить, как вы собираетесь использовать интерфейс навигации. Поскольку это налагает основополагающее значение на организацию ваших данных, вы должны использовать его только для следующих конкретных целей:

  • Установите его прямо как контроллер кореневого вида окна.
  • Установите его в качестве контроллера вида вкладки в интерфейсе панели вкладок (Tab bar).
  • Установите его в качестве одного из двух кореневых контроллеров видов в интерфейсе с разделением (Split View). (только для iPad).
  • Представить его модально из другого контроллера вида.
  • Отобразить его из popover. (только iPad).

В первых трех сценариях, контроллер навигации обеспечивает решающую часть вашего основного интерфейса и остается таким, пока приложение не выходит. Последние два сценария отражают более временное использование контроллеров навигации, в этом случае применение контроллера навигации является идентичным процессу для других контроллеров видов контента. Разница лишь в том, что контроллер навигации продолжает оказывать дополнительные навигационные функции, не доступные с помощью одного контроллера представления вида контента.

Задание контроллеров видов контента для интерфейса навигации

Каждый интерфейс навигации имеет один уровень данных, представляющий корневой уровень. Этот уровень является отправной точкой вашего интерфейса. Например, приложение "Фото" отображает список доступных фотоальбомов на корневом уровне его иерархической структуры данных. Выбирая фотоальбом осуществляется переход к отображению миниатюр фотографий в этом альбоме, выбрав фото осуществляется показ большой версии фотографии.

Чтобы реализовать интерфейс навигации, вы должны решить, какие данные, необходимо представить на каждом уровне иерархии данных. Для каждого уровня, вы должны предоставить контроллер вида контента для управления и представления данных на данном уровне. Если презентация на нескольких уровнях и одна и та же, вы можете создать несколько экземпляров одного и того же класса контроллера вида и настроить каждый из них для управления своим ​​собственным набором данных.

Создание интерфейса навигации используя Storyboard

Если вы создаете новый проект Xcode, с использованием шаблона Master-Detail Application, создается контроллер навигации в Storyboard, установленный в качестве первой сцены.

Чтобы создать контроллер навигации в Storyboard, выполните следующие действия:

  1. Перетащите navigation controller из библиотеки
  2. Interface Builder создаст навигационный контроллер и контроллер вида, а также связь между ними. Эта связь идентифицирует контроллер вида, как корневой для навигационного контроллера.
  3. Отобразите его в качестве первого контроллера представления вида, выбрав опцию Is Initial View Controller в инспекторе Атрибутов (или представьте контроллер вида в пользовательском интерфейсе по-другому.)

Создание интерфейса навигации программно

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

Выполните следующие шаги для создания навигационного контроллера програмно:

  1. Создайте корневой контроллер вида (root view controller) для интерфейса навигации.

    Этот объект является контроллером вида верхнего уровня в стеке навигации. Панель навигации отображает кнопку назад, когда отображается его вид и контроллер вида не может быть извлечен из стека навигации.

  2. Создайте контроллер навигации, инициализировав его с помощью метода initWithRootViewController:.
  3. Установите контроллер навигации в качестве корневого вида контроллера вашего окна (или в противном случае добавьте его в интерфейс).

Пример простой реализации applicationDidFinishLaunching:, в котором создается контроллер навигации и устанавливается в качестве корневого вида контроллера главного окна приложения.

- (void)applicationDidFinishLaunching:(UIApplication *)application
{
    UIViewController *myViewController = [[MyViewController alloc] init];
    navigationController = [[UINavigationController alloc]
                                initWithRootViewController:myViewController];
 
    window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    window.rootViewController = navigationController;
    [window makeKeyAndVisible];
}

Применение полноэкранной компоновки навигационного контроллера

Как правило, навигационный интерфейс отображает пользовательский контент в промежутке между нижней частью панели навигации и в верхней частью панели инструментов или панели вкладок. Тем не менее, вместо этого, контроллер вида может попросить, чтобы его вид отображался как полноэкранный макет. Такое расположение позволяет отображать максимально видимую часть контента для пользователя и может быть полезно для отображения фото или в других случаях.

При определении, должен ли вид быть изменен в размерах, чтобы заполнить всю или большую часть экрана, навигационный контроллер рассматривает несколько факторов, включая следующие:

  • Является основное окно (или родительский вид) соответствующего размера, чтобы заполнить все границы экрана?
  • Настроена ли панель навигации как полупрозрачная (translucent)?
  • Настроена ли панель инструментов навигации (если используется) как полупрозрачная (translucent)?
  • Установлено ли свойство wantsFullScreenLayout нижележащего контроллера вида, в YES?

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

  1. Настройте фрейм вашего пользовательского представления вида, чтобы он заполнял границы экрана.

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

  2. Для скрываемой навигационной панели (navigation bar), установите свойство translucent вашего контроллера навигации в YES.
  3. Для скрываемой необязательной панели инструментов (tool bar), установите свойство translucent вашего контроллера панели инструментов в YES.
  4. Для скрываемой строки состояния, установите свойство wantsFullScreenLayout вашего контроллера вида в YES.

При представлении навигационного интерфейса, окно или вид, к которому вы добавляете ваш вид навигации также должны быть рассчитаны соответствующим образом. Если ваше приложение использует контроллер навигации в качестве основного интерфейса, то ваше главное окно должно быть рассчитано в соответствии с размерами экрана. Другими словами, вы должны установить его размер, чтобы соответствовать свойству bounds класса UIScreen (вместо свойства applicationFrame). На самом деле, для интерфейса навигации, как правило, лучше, создать свое окно с полноэкранными границами в любых ситуациях, поскольку контроллер навигации регулирует размер своих видов, чтобы разместить строку состояния автоматически в любом случае.

Изменение стека навигации

Вы несете ответственность за создание объектов, которые находятся в стеке навигации. При инициализации объекта контроллера навигации, вы должны предоставить контроллер вида контента для отображения корневого контента иерархии данных. Вы можете добавлять или удалять контроллеры видов программно или в ответ на действия пользователя. Класс контроллера навигации предоставляет несколько вариантов управления содержимым стека навигации. Эти параметры охватывают различные сценарии, с которыми вы можете столкнуться в вашем приложении. В следующей таблице перечислены эти сценарии и как вы реагируете на них.

СценарийОписание
Отображение следующего уровня иерархии данныхКогда пользователь выбирает элемент, отображаемый верхним контроллером представления вида, можно использовать переход (segue) или метод pushViewController:animated:, чтобы подтолкнуть новый контроллер вида в стек навигации. Новый контроллер вида отвечает за представление содержимого выбранного элемента.
Возврат вверх по иерархии данныхКонтроллер навигации обычно предоставляет кнопку назад, чтобы изъять верхний контроллер вида из стека и вернуться к предыдущему экрану. Вы также можете удалить верхний контроллер вида программно с помощью метода popViewControllerAnimated:.
Восстановление стека навигации в предидущее состояниеКогда ваше приложение запускается, вы можете использовать метод setViewControllers:animated:, чтобы восстановить контроллер навигации в предыдущее состояние. Например, можно использовать этот метод для возвращения пользователя на тот экран просмотра, из которого он в последний раз вышел из приложения.

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

Вы также можете использовать этот метод, чтобы перейти к произвольному месту в иерархии данных. Переход в произвольное место может легко привести к путанице, поэтому вы должны обратить особое внимание на связь, которая явно осуществляется с пользователем.

Возврат пользователя к корневому контроллеру видаДля возврата к верхней части навигационного интерфейса, используйте метод popToRootViewControllerAnimated:. Этот метод удаляет все, кром кореневого контроллера вида из стека навигации.
Возврат на произвольное количество уровней в иерархииЧтобы вернуться более чем на один уровень за раз, используйте метод popToViewController:animated:. Вы можете использовать этот метод в тех случаях, когда вы используете контроллер навигации для управления редактированием пользовательского контента (а не представления контента модально). Если пользователь решит отменить операцию после того, как прошел несколько экранов редактирования, вы можете использовать этот метод, чтобы удалить все экраны редактирования разом, а не по одному.

Мониторинг изменений в стеке навигации

Всякий раз, когда вы нажимаете контроллер вида, контроллер навигации посылает сообщения затрагиваемым контроллерам видов. Контроллер навигации также отправляет сообщения своему делегату, когда меняется его стек. Рисунок ниже показывает последовательность событий, которые происходят во время операции и соответствующие сообщения, отправляемые для пользовательских объектов на каждом этапе. Новый контроллер вида отражает контроллер вида, который собирается стать самым верхним контроллером вида в стеке.

uinavigationcontroller ios notifications

Настройка внешнего вида Навигационного бара

Структура панели навигации аналогична структуре контроллера навигации во многих отношениях. Как и у контроллера навигации, панель навигации является контейнером для контента, который обеспечивается другими объектами. В случае панели навигации, содержание обеспечивается одним или несколькими объектами UINavigationItem, которые хранятся с использованием структуры данных, известной как стек элементов навигации. Каждый элемент навигации предоставляет полный набор видов и контента, который будет отображаться в навигационной панели.

Панель навигации помещает элементы в трех основных положениях: влево, вправо, и по центру. В таблице ниже перечислены свойства класса UINavigationItem, которые используются для настройки каждой из этих позиций. При настройке элемента навигации для использования с контроллером навигации, необходимо учесть, что пользовательские элементы управления в некоторых позициях могут быть проигнорированы в интересах элементов управления навигацией. Описание каждой позиции включает в себя информацию о том, как используются ваши пользовательские объекты.

ПозицияСвойствоОписание
LeftbackBarButtonItem leftBarButtonItemВ интерфейсе навигации, контроллер навигации назначает кнопку Назад в левом положении по умолчанию. Чтобы получить кнопку Назад по умолчанию, присвоенную контроллеру навигации, запросите значение свойства backBarButtonItem.

Чтобы назначить персональную кнопку или представление в левое положение, и тем самым заменить кнопку по умолчанию Назад, назначьте объект UIBarButtonItem свойству leftBarButtonItem.

CentertitleViewВ интерфейсе навигации, контроллер навигации отображает настраиваемое представление с названием вашего вида контента контроллера по умолчанию. Вы можете заменить этот вид в соответствии с вашими пожеланиями на собственное настраиваемое представление вида.

Если вы не предоставляете свой вид пользовательского заголовка, навигационная панель отображает настраиваемое представление со строкой заголовка навигационного элемента. Или, если элемент навигации не обеспечивает заголовок, навигационная панель использует заголовок представления контроллера.

RightrightBarButtonItemЭта позиция изначально пуста. Она, как правило, используется для размещения кнопки для редактирования или изменения текущего экрана. Вы также можете разместить пользовательские виды здесь, обернув вид в объект UIBarButtonItem.

Показ и скрытие навигационного бара

Когда панель навигации используется в сочетании с контроллером навигации, вы всегда используете метод setNavigationBarHidden:animated: класса UINavigationController для отображения и скрытия панели навигации. Вы никогда не должны скрывать панель навигации, изменением свойства hidden объекта UINavigationBar напрямую. В дополнение к показу или скрытию панели, используя метод контроллера навигации передоставляет вам более сложные модели поведения даром. В частности, если контроллер вида показывает или скрывает панель навигации в своем viewWillAppear: методе, контроллер навигации оживляет внешний вид или исчезновение бара, чтобы совпасть с появлением нового контроллера представления вида.

Поскольку пользователю необходимо иметь кнопку назад на навигационной панели для перемещения к предыдущему экрану, вы никогда не должны скрывать панель навигации, не предоставив пользователю некоторый путь, для возврата к предыдущему экрану. Наиболее распространенным способом обеспечения навигационного обеспечения для перехвата событий прикосновения и использования их для переключения видимости панели навигации. Например, фото приложение делает это, когда одиночное изображение отображается во весь экран. Кроме того, можно использовать смахивающие жесты и использовать их для выталкивания текущего контроллера представления из стека.

Изменение объектов навигационного бара напрямую

В интерфейсе навигации, навигационный контроллер владеет своим UINavigationBar объектом и отвечает за управление им. Не допустимо изменять объект панели навигации или изменять его границы, размеры или значения прозрачности напрямую. Тем не менее, есть несколько свойств, которые можно изменять, включая следующие:

  • barStyle
  • translucent
  • tintColor - Оттенок цвета, применяемый к навигационным элементам и элементам кнопок на панели. В iOS 7 все подклассы UIView получают свое поведение для tintColor от базового класса.

Создание элемента пользовательской кнопки бара навигации.

// View 3 - Пользовательский вид для правой кнопки
UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:
                                      [NSArray arrayWithObjects:
                                          [UIImage imageNamed:@"up.png"],
                                          [UIImage imageNamed:@"down.png"],
                                          nil]];
 
[segmentedControl addTarget:self action:@selector(segmentAction:) forControlEvents:UIControlEventValueChanged];
segmentedControl.frame = CGRectMake(0, 0, 90, kCustomButtonHeight);
segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;
segmentedControl.momentary = YES;
 
defaultTintColor = segmentedControl.tintColor;    // Сохраняем для последующего использования (если нужно).
UIBarButtonItem *segmentBarItem = [[UIBarButtonItem alloc] initWithCustomView:segmentedControl];
self.navigationItem.rightBarButtonItem = segmentBarItem;

Настройка элементов навигации вашего контроллера вида программным способом является наиболее распространенным подходом для большинства приложений. Хотя вы можете создавать элементы панели с кнопками с помощью Interface Builder, часто гораздо проще создавать их программно. Вы должны создать элементы в методе viewDidLoad вашего контроллера вида.

Использование Edit и Done кнопок

Представления видов, которые поддерживают редактирование на месте могут включать в себя специальный тип кнопки в их навигационной панели, которая позволяет пользователю переключаться назад и вперед между режимами отображения и редактирования. Метод editButtonItem из UIViewController возвращает предварительно настроенную кнопку, которая при нажатии переключает между Edit и Done кнопками и вызывает метод контроллера setEditing:animated: с соответствующими значениями. Чтобы добавить эту кнопку к навигационной панели вашего контроллера вида, вы должны использовать код, подобный следующему:

myViewController.navigationItem.rightBarButtonItem = [myViewController editButtonItem];

Если вы включаете эту кнопку в панель навигации, необходимо также переопределить метод setEditing:animated: и использовать его для изменения режима отображения видов из иерархии.

Отображение навигационной панели инструментов

Начиная с прошивки 3.0 и выше, интерфейс навигации может отображать панель инструментов и заполнить ее элементами, предоставляемыми видимым в данный момент контроллером представления вида. Сама панель инструментов управляется объектом контроллера навигации. Поддержка панели инструментов на этом уровне необходима для того, чтобы создать плавные переходы между экранами. Когда верхний контроллер представления измененяет стек навигации, контроллер навигации оживляет изменения между различными наборами элементов панели инструментов. Он также создает гладкую анимацию в случаях, когда вы хотите переключать видимость панели инструментов для конкретного контроллера вида.

Чтобы настроить панель инструментов для навигационной интерфейса, необходимо выполнить следующие действия:

  • Показать панель инструментов, установив свойство toolbarHidden объекта контроллера навигации в NO.
  • Связать массив объектов UIBarButtonItem с свойством toolbarItems каждого из ваших контроллеров вида контента.

Настройка панели инструментов с центральным сегментным элементом управления.

- (void)configureToolbarItems
{
   UIBarButtonItem *flexibleSpaceButtonItem = [[UIBarButtonItem alloc]
                        initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
                        target:nil action:nil];
 
   // Создаем и настраиваем segmented control
   UISegmentedControl *sortToggle = [[UISegmentedControl alloc]
                        initWithItems:[NSArray arrayWithObjects:@"На продаже",
                                        @"Проданные", nil]];
   sortToggle.segmentedControlStyle = UISegmentedControlStyleBar;
   sortToggle.selectedSegmentIndex = 0;
   [sortToggle addTarget:self action:@selector(toggleSorting:)
               forControlEvents:UIControlEventValueChanged];
 
   // Создание элемента кнопки бара для segmented control
   UIBarButtonItem *sortToggleButtonItem = [[UIBarButtonItem alloc]
                                    initWithCustomView:sortToggle];
 
   // Устанавливаем наши элементы tool bar
   self.toolbarItems = [NSArray arrayWithObjects:
                         flexibleSpaceButtonItem,
                         sortToggleButtonItem,
                         flexibleSpaceButtonItem,
                         nil];
}

В дополнение к установке элементов панели инструментов во время инициализации, контроллер вида также может изменить свой существующий набор элементов панели инструментов динамически с использованием метода setToolbarItems:animated:. Этот метод полезен в ситуациях, когда вы хотите обновить команды панели инструментов, чтобы отобразить некоторые другие возможности действий пользователя. Например, вы можете использовать его, чтобы реализовать набор иерархических элементов панели инструментов, в результате чего нажав кнопку на панели инструментов отображается набор связанных дочерних кнопок.

Отображение и скрытие панели инструментов

Чтобы скрыть панель инструментов для конкретного контроллера вида, установите hidesBottomBarWhenPushed свойство этого контроллера вида в YES. Когда контроллер навигации встречает контроллер представления с этим свойством, установленным в YES, он генерирует соответствующий переход анимации, когда контроллер вид помещается (или удаляется из него) в стек навигации.

Если вы хотите скрыть панель инструментов временно, вы можете вызвать в метод setToolbarHidden:animated: контроллера навигации в любой момент. Наиболее распространенный способ использовать этот метод заключается в сочетании его с вызовом методом setNavigationBarHidden:animated:, чтобы создать временный вид в полноэкранном отображении. Например, фото приложение переключает видимость обоих баров, когда оно выводит одну фотографию и пользователь нажимает на экран.

 
 
homeЗаметили ошибкукарта сайта 
   Made on a Mac