Урок 3.7 Переходы и навигационные контроллеры

Урок 3.7 Переходы и навигационные контроллеры

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

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


Что Вы Изучите

  • Как перейти от одного контроллера представлений к другому
  • Как добавить и настроить навигационный контроллер
  • Как передать информацию от одного контроллера представлений к другому

Словарь


Связанные ресурсы:

  • Показ и скрытие контроллеров представлений
  • Справочник API: UINavigationController
  • Справочник API: UINavigationBar

 

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

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

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

 

Переходы (Segues)

Переход (segue) определяет переход от одного контроллера представлений к другому. Обычно он начинается, когда пользователь нажимает кнопку или строку таблицы, и заканчивается, когда новый контроллер представлений отображается. Аналогично созданию выходов (outlets) и действий (actions), вы определяете переходы в Interface Builder, соединяя начальную и конечную точки, щелкая и перетаскивая от одной сцены к другой. Вы также можете запускать переходы программно.

Помимо самого перехода, segue также определяет метод представления контроллера представлений. Одним из распространенных методов является модальное представление, которое размещает новый контроллер представлений поверх предыдущего. На маленьких экранах модальное представление всегда будет появляться на весь экран. Чтобы адаптировать пользовательский интерфейс для более крупных устройств, вы можете настроить модальное представление, чтобы оно появлялось в виде всплывающего окна (popover), листа формы (form sheet) или на весь экран.

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

Когда новый контроллер представлений отображается модально, вы можете использовать "unwind segue", чтобы позволить пользователю закрыть новый контроллер представлений и вернуться к предыдущему.

Создание триггерных переходов

 

Чтобы попрактиковаться в переходах между контроллерами представлений, вы создадите простое приложение, которое переключает цвета светофора. Начните с создания нового проекта в Xcode, используя шаблон iOS App. Назовите проект "TrafficSegues". При создании проекта убедитесь, что опция интерфейса установлена на Storyboard. Выберите основной storyboard в Project navigator, чтобы открыть ваш проект в Interface Builder.

Добавьте UIButton в центр представления, используя направляющие для выравнивания, чтобы помочь его позиционировать. Нажмите кнопку иконка "Align" и выберите “Horizontally in Container” и “Vertically in Container”, чтобы создать два ограничения, которые центрируют кнопку для всех размеров экрана.

Найдите View Controller в библиотеке объектов и перетащите этот объект на холст, расположив его справа от первого контроллера представлений. Используя инспектор атрибутов (Attributes inspector), задайте левому контроллеру представлений красный фон, а правому контроллеру представлений — желтый фон. (На скриншотах используются более светлые оттенки цветов для большей ясности.)

Представьте, что вы хотите перейти к желтому контроллеру представлений, когда пользователь нажимает вашу UIButton в красном контроллере представлений. Удерживая нажатой клавишу Control, выберите кнопку и перетащите указатель на второй контроллер представлений. Это действие должно выделить желтый контроллер представлений, указывая на то, что он является допустимой конечной точкой для перехода (segue). 1 

Когда вы отпустите кнопку мыши или трекпада, вы увидите всплывающее окно, которое позволяет указать метод представления перехода (segue). Существует множество типов переходов, но сосредоточьте свое внимание на "Present Modally" и "Show". "Present Modally" будет отображать желтый контроллер представлений поверх красного, используя анимацию сдвига снизу вверх. Вы видите эту анимацию в приложении Почта, когда начинаете писать новое письмо, или в Контактах, когда выбираете создать новый контакт.

Переход Show также выполняет модальное представление до тех пор, пока к сцене storyboard не будет добавлен навигационный контроллер. Вы добавите его позже в уроке. А пока выберите Show. Появится стрелка от красного контроллера представлений к желтому контроллеру, указывающая на переход (segue).  2 

Соберите и запустите ваше приложение. Когда вы нажмете на вашу кнопку UIButton, вы должны увидеть анимацию появления желтого представления снизу вверх поверх красного представления.

Теперь добавьте третий контроллер представлений, расположив его справа от желтого представления. Установите его фоновый цвет на зеленый. Как и в предыдущих шагах, добавьте UIButton в желтое представление, создайте ограничения для центрирования, затем удерживая Control, перетащите от кнопки к зеленому контроллеру представлений и определите переход Show.

Когда вы соберете и запустите приложение, нажатие кнопки на красном контроллере представлений модально покажет желтый контроллер представлений, а нажатие кнопки на желтом контроллере представлений модально покажет зеленый контроллер представлений.

Обратите внимание, что красный контроллер представлений имеет тип ViewController. Вы не назначили класс для желтого и зеленого контроллеров представлений, поэтому они будут общими экземплярами UIViewController. Это различие будет важно, когда вы реализуете переход unwind segue.

Откат Перехода (Unwind Segue)

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

Для начала выберите ViewController в Project navigator и добавьте следующий метод сразу под функцией viewDidLoad():

 

@IBAction func unwindToRed(unwindSegue: UIStoryboardSegue) {
 
}

 

Вы можете назвать метод как угодно, но он должен принимать UIStoryboardSegue в качестве единственного параметра.

Переходы unwind segue могут быть трудны для понимания с первого взгляда. Добавляя функцию, которая принимает UIStoryboardSegue в качестве параметра в определение контроллера представлений любой сцены, вы сообщаете Interface Builder, что эта сцена является допустимым местом назначения для перехода unwind segue.

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

Посмотрите, как это работает. Вернитесь к Main (основному) storyboard и добавьте кнопку в центр зеленого представления. Обновите текст кнопки, чтобы он был "Dismiss".

Удерживая Control, перетащите кнопку Dismiss к объекту Exit в верхней части сцены контроллера представлений. Когда вы отпустите кнопку мыши или трекпада, появится всплывающее окно, в котором перечислены все доступные точки назначения для отмены. В данном случае есть только один вариант: unwindToRedWithUnwindSegue, который соответствует методу, который вы добавили в определение ViewController. Выберите его.

Соберите и запустите приложение. Когда вы нажмете кнопку Dismiss, должно произойти unwind-переход, который вернет вас обратно к красному контроллеру представлений.

Навигационные контроллеры

Модальные переходы (segues) являются предпочтительным методом перехода от одного контекста к другому в вашем приложении. Например, в приложении Почта на iOS, нажатие кнопки "Compose" (Создать) переходит от чтения сообщений к написанию сообщений. Кнопка "Cancel" (Отмена) всегда доступна, если пользователь решит вернуться к предыдущему контексту.

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

Нажатие кнопки "Back" (Назад) в верхнем левом углу или свайп назад убирает верхний контроллер представлений и возвращает к следующему по высоте контроллеру представлений, с анимацией справа налево. Закрытие контроллера представлений с вершины стека называется "popping off" (извлечение из стека).

Навигационные контроллеры управляют стеком контроллеров представлений и обеспечивают анимацию при навигации между связанными представлениями.

Эта структура push-and-pop похожа на мытье стопки грязных тарелок. После того как вы помоете и высушите каждую тарелку, вы кладете ее в шкаф. Первая тарелка, которую вы помоете, окажется на дне стека, а последняя — на вершине. Позже, когда вы возьмете чистую тарелку из шкафа, вы возьмете последнюю вымытую тарелку.

Теперь представьте, что каждая тарелка — это контроллер представлений, который добавляется на экран. По мере того как вы продолжаете добавлять новые контроллеры представлений, первый из них — известный как корневой (root) — перемещается дальше вниз по стеку. Множественные нажатия кнопки "Back" в конечном итоге вернут вас к корневому контроллеру представлений, после чего кнопка "Back" исчезнет. Каждый навигационный контроллер имеет корневой контроллер представлений.

Еще один способ представить навигационный контроллер — это рассматривать его как отражение иерархической структуры данных. В случае приложения Почта, список аккаунтов (корень) дает возможность нажать, чтобы увидеть папки аккаунта. Нажатие на каждую папку показывает ее сообщения. Настройки работают аналогично. Есть список категорий настроек (корень), из которых можно выбрать одну, чтобы увидеть настройки или подкатегории внутри нее, каждый раз погружаясь глубже в иерархию. В приведенном выше примере из корня выбирается "General" (Общие), а затем внутри этого "Accessibility" (Специальные возможности). Добавление контроллера представлений в стек углубляет вас в иерархию, а извлечение контроллера представлений из стека возвращает вас по иерархии к корню.

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

Чтобы добавить навигационный контроллер в вашу сцену, выберите красный контроллер представлений. Затем нажмите кнопку "Embed In" на нижней панели инструментов и выберите "Navigation Controller". Либо перейдите в строку меню Xcode и выберите Editor > Embed In > Navigation Controller.

Любой из этих методов добавит навигационный контроллер в начало сцены и установит красный контроллер представлений как его корневой.

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

  • Переходы Show между красным, желтым и зеленым контроллерами представлений адаптировались к Show (Push), а не Present Modally. (Это ключевая особенность перехода Show: он адаптирует метод представления в зависимости от того, используется ли он внутри навигационного контроллера или независимо.)
  • Кнопка Dismiss по-прежнему возвращает к красному контроллеру представлений, но делает это путем извлечения контроллеров представлений из стека, а не их закрытия.
  • В верхней части каждого представления теперь находится прозрачная навигационная панель, которая предоставляет место для кнопки "Back", а также для заголовка и дополнительных кнопок.
  • В Outline документа теперь включена сцена Navigation Controller Scene, которая содержит Navigation Bar.

Навигационная панель

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

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

Элемент навигации

Каждый UIViewController имеет navigationItem, который можно использовать для настройки его навигационной панели. Когда вы добавили навигационный контроллер на предыдущем этапе, Interface Builder автоматически добавил элемент навигации к корневому (красному) контроллеру представлений.

В Outline документа выберите элемент навигации для красного контроллера представлений и откройте инспектор атрибутов. Введите “Red” в атрибуте заголовка (Title). 

Соберите и запустите приложение. Когда вы перейдете на желтый экран, вы заметите, что кнопка "Back" теперь отображает текст "Red". Как это произошло? Кнопка "Back" использует заголовок предыдущего контроллера представлений в качестве своего текста. Однако, если у предыдущего контроллера представлений нет заголовка, кнопка "Back" просто отображает текст "Back". Если вы хотите, чтобы кнопка "Back" использовала другой текст, например "Go To Red", вы можете ввести его в поле Back Button в инспекторе атрибутов элемента навигации красного контроллера представлений. 

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

Установите заголовки желтого и зеленого контроллеров представлений, выбрав их элемент навигации и используя инспектор атрибутов для создания заголовков "Yellow" и "Green".

Помимо заголовков и кнопок "Back", элементы навигации могут включать специальный тип кнопок, известных как барные кнопки (bar buttons), которые могут появляться как на навигационных панелях, так и на панелях инструментов. Найдите Bar Button Item в библиотеке объектов и поместите его в правый верхний угол навигационной панели зеленого контроллера представлений. 

Нажмите на барную кнопку, которую вы только что добавили, и откройте инспектор атрибутов. В выпадающем меню System Item вы увидите часто используемые варианты кнопок, такие как Add (Добавить), Save (Сохранить) и Cancel (Отмена). Выберите один или два варианта, чтобы увидеть, как изменяется текст кнопки. Попробуйте также поиграть с атрибутами Style (Стиль) и Tint (Цвет). Свойства Bar Item позволяют вам дополнительно настраивать вашу кнопку. Например, вы можете использовать поле Image (Изображение), чтобы заменить текстовый заголовок изображением или иконкой.

На данный момент обновите свойство Title барной кнопки на "Pop". (Обратите внимание, что это изменение изменяет опцию System Item на Custom.)

Далее вы можете связать эту новую барную кнопку с unwind segue.  Обратитесь к тем же шагам, которые вы использовали для подключения кнопки Dismiss. После завершения вы можете удалить кнопку Dismiss.

Теперь ваш storyboard содержит все необходимые переходы (segues). Соберите и запустите приложение, чтобы увидеть заголовки и кнопку, которую вы только что добавили. Обратите внимание, что нажатие на кнопку Pop возвращает вас к красному контроллеру представлений.

Большие заголовки

Вы могли заметить, что в системных приложениях, таких как Настройки, заголовок навигационной панели на основном экране выглядит намного больше, чем на последующих сценах. Этот большой заголовок можно добавить в ваши собственные приложения, выбрав навигационную панель в Interface Builder, а затем установив флажок “Prefers Large Titles” в инспекторе атрибутов.  10 

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

Опция "Always" (Всегда) обеспечит, что заголовок этого элемента навигации всегда будет большим; опция "Never" (Никогда) обеспечит, что заголовок этого элемента навигации никогда не будет большим; а опция "Automatic" (Автоматически) будет наследовать поведение предыдущего контроллера представлений в навигационном стеке. Если у вас нет конкретной причины делать иначе, хорошей практикой является установка большого заголовка для корневого контроллера представлений, а для последующих контроллеров использовать меньшие заголовки.

 

Передача информации

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

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

Начните с перетаскивания текстового поля из библиотеки объектов на красный контроллер представлений, разместив его прямо над кнопкой. В этом примере не беспокойтесь о добавлении ограничений. 12 

Создайте outlet для текстового поля и назовите его “textField”. 13  Вам нужно будет ссылаться на текстовое поле в коде, чтобы получить доступ к тексту и соответственно обновить заголовок целевого контроллера представлений.

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

У каждого UIViewController есть метод prepare(for:sender:), который вызывается перед выполнением перехода (segue) из контроллера представлений. Начните вводить “prepare” ближе к концу определения ViewController, но перед закрывающей скобкой. Xcode предложит вам помочь завершить имя метода. Выберите prepare(for segue: UIStoryboardSegue, sender: Any?) и нажмите клавишу Return, чтобы добавить метод. 14 

Первый аргумент этого метода — это сам segue. Segue содержит несколько свойств, которые помогают передавать информацию через него:

  • identifier — имя segue, которое отличает его от других segues. Вы можете установить это свойство в Interface Builder, используя инспектор атрибутов.
  • destination — контроллер представлений, который будет отображаться после завершения segue. Хотя значение является UIViewController, вам может понадобиться привести его к конкретному подклассу UIViewController, чтобы получить доступ к свойствам, доступным только в этом подклассе.

Поскольку на красном контроллере представлений есть только один segue, identifier не нужен. И поскольку ваша цель — обновить свойство title элемента навигации, а каждый UIViewController имеет это свойство, нет необходимости в приведении типа. Таким образом, код для установки заголовка элемента навигации целевого контроллера достаточно прост:

 

override func prepare(for segue: UIStoryboardSegue, sender:
Any?) {
    segue.destination.navigationItem.title = textField.text
}

 

Соберите и запустите ваше приложение. Затем введите короткую строку в текстовое поле. Когда вы нажмете кнопку, метод, который вы только что добавили, обновит заголовок на желтом экране.

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

Создание программных переходов (segues)

Иногда вам нужно использовать некоторую логику, чтобы определить, выполнять ли переход (segue). Каждый segue, который вы создали до этого момента, включал перетаскивание от кнопки к контроллеру представлений. Когда вы создаете segue таким образом, он всегда будет выполняться при нажатии кнопки. В этом разделе вы определите несколько универсальных segues между контроллерами представлений и решите программно, должны ли они быть выполнены.

Прежде чем начать, восстановите ваше приложение до чистого состояния. Удалите все существующие segues, элементы управления и метки с вашего storyboard. Также вам нужно удалить все созданные вами outlets, а также методы prepare(for:sender:) и unwindToRed(segue:). Ваше приложение должно выглядеть так, когда вы будете готовы:

В этом примере вы разместите две кнопки на красном контроллере представлений. Одна кнопка будет переходить на желтый экран, а другая — на зеленый. В пользовательском интерфейсе также будет включен UISwitch, который определит, будут ли выполнены переходы. Если переключатель включен, переход может быть выполнен; в противном случае переход не произойдет.

Начните с размещения двух кнопок и переключателя из библиотеки объектов на красный экран. Обновите заголовок одной кнопки, чтобы он отображал "Push to Yellow", а другой — "Push to Green". Разместите переключатель под кнопками, как показано на рисунке. 15  В этом примере не беспокойтесь о создании ограничений для позиционирования представлений для каждого размера экрана и ориентации.

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

Чтобы выполнить переходы в коде, вам нужно присвоить каждому переходу действительную строку идентификатора. Выберите сам переход, нажав на линию перехода. 17  В инспекторе атрибутов назовите один идентификатор "Yellow" и другой "Green". 18 

Вам нужно будет проверить состояние UISwitch в коде, чтобы определить, выполнять ли переход. Для этого вам нужно создать outlet для переключателя. Откройте assistant editor и перетащите от переключателя к действительному месту в определении ViewController.

 

@IBOutlet var segueSwitch: UISwitch!

 

Создайте действие для каждой кнопки, перетащив от кнопки к действительному месту в определении ViewController.

 

@IBAction func yellowButtonTapped(_ sender: Any) {
 
}
 
@IBAction func greenButtonTapped(_ sender: Any) {
 
}

 

Чтобы выполнить переход программно, существует метод, который находится в контроллерах представлений, называемый performSegue(withIdentifier:sender:). Первый параметр этого метода принимает строку (String), которая соответствует идентификатору, который вы назначили переходам в инспекторе атрибутов. Параметр sender представляет собой дополнительную информацию, которую вы можете передать переходу о том, какой элемент управления вызвал переход, но в этом примере это не нужно и может быть установлено в nil.

Вызовите performSegue(withIdentifier:, sender:) в каждом методе только в том случае, если переключатель установлен в положение "On".

 

@IBAction func yellowButtonTapped(_ sender: Any) {
    if segueSwitch.isOn {
        performSegue(withIdentifier: “Yellow”, sender: nil)
    }
}
 
@IBAction func greenButtonTapped(_ sender: Any) {
    if segueSwitch.isOn {
        performSegue(withIdentifier: “Green”, sender: nil)
    }
}

 

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

Напомним, что свойство identifier у UIStoryboardSegue, передаваемого в prepare(for:sender:), сообщает вам имя перехода, который собирается быть выполнен. Изучите документацию API для shouldPerformSegue(withIdentifier:sender:). Как можно перенести проверку segueSwitch.isOn в shouldPerformSegue(withIdentifier:sender:), а не внутри каждого действия кнопки?

 

Лабораторная работа — вход в систему

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

Инструкции в этой лабораторной работе не будут охватывать ограничения и Auto Layout. Но по мере выполнения шагов уделите некоторое время, чтобы убедиться, что ваши представления адаптируются к разным размерам экрана и ориентациям.

Создайте новый проект под названием "Login", используя шаблон iOS App.

Шаг 1

Создайте сцены на storyboard с простыми переходами

  • Используя изображение на предыдущей странице, настройте ваш storyboard таким образом, чтобы он содержал два контроллера представлений: первый для экрана входа и второй для стартового экрана.
  • Добавьте два текстовых поля и три кнопки на экран входа, также следуя изображению. Измените текст первой кнопки на "Log In", второй на "Forgot Username", и третий на "Forgot Password". 19 
  • Для двух текстовых полей используйте инспектор атрибутов, чтобы установить текст-заполнитель на "Username" и "Password". 20  Чтобы скрыть вводимый текст в текстовом поле для пароля, установите флажок Secure Text Entry в нижней части инспектора атрибутов.
  • Создайте переход Show от кнопки входа к стартовому экрану.
  • Используя инспектор атрибутов для контроллера представлений стартового экрана, найдите опцию Presentation и выберите Full Screen. Это позволяет отображать представление на весь экран, а не в виде карточки, которую можно закрыть свайпом вниз. Вы хотите, чтобы пользователь чувствовал, что вошел в ваше приложение — экран входа не должен оставаться в фоне.
  • Запустите приложение. Убедитесь, что вы можете перейти с экрана входа на стартовый экран. Поскольку вы еще не настроили способ передачи информации от входа, ваш стартовый экран будет пустым.

 

Шаг 2

Добавьте навигационный контроллер и подготовьте переход

  • Встроите ваш контроллер представлений для входа в навигационный контроллер и добавьте заголовок к элементу навигации. Измените опцию Large Title на Always. Выберите навигационную панель навигационного контроллера и установите флажок Prefers Large Titles.
  • Выберите элемент навигации для стартового экрана. Измените опцию Large Title на Always.
  • В файле ViewController добавьте метод prepare(for:sender:). Используйте автозаполнение для правильного переопределения метода.
  • Создайте outlet для текстового поля имени пользователя в файле ViewController.
  • В методе prepare(for:sender:) установите заголовок элемента навигации контроллера представлений назначения в текст из текстового поля имени пользователя.
  • Запустите приложение и убедитесь, что текст, который вы вводите в текстовое поле имени пользователя, отображается в заголовке стартового экрана, когда вы нажимаете кнопку входа.

Шаг 3

Добавьте программные переходы

  • Создайте переход от контроллера представлений для входа (не от кнопки входа) к контроллеру представлений для стартового экрана. Обязательно дайте переходу описательный идентификатор.
  • Создайте outlet для каждой из двух оставшихся кнопок (кнопки "Forgot Username" и кнопки "Forgot Password"), и дайте им описательные имена, например "forgotUserNameButton".
  • Создайте действие для каждой из кнопок.
  • В каждом действии вызовите метод performSegue(withIdentifier:sender:), передавая идентификатор недавно созданного перехода. Вместо того чтобы устанавливать sender в nil, установите sender в кнопку, которая была нажата. Например, если идентификатор перехода ForgottenUsernameOrPassword, то внутри действия кнопки это может выглядеть следующим образом:

 

performSegue(withIdentifier: "ForgottenUsernameOrPassword", sender: sender)

 

  • Ранее в этом уроке вы узнали, что метод prepare(for:sender:) предоставляет доступ к идентификатору вызванного перехода (segue). Теперь, когда у вас есть два возможных идентификатора, вам нужно использовать управляющие конструкции, чтобы передать различную информацию на стартовый экран в зависимости от того, какой переход был вызван. Если был вызван переход входа в систему, вы хотите, чтобы заголовок стартового экрана был именем пользователя. Однако, если была нажата кнопка "Forgot Password", вы хотите, чтобы заголовок был "Forgot Password". Аналогично, нажатие кнопки "Forgot Username" изменит заголовок на "Forgot Username". Прежде чем читать дальше, уделите минуту, чтобы попробовать сделать это самостоятельно, используя segue.identifier, sender, приведение типов и операторы if.
  • Ничего страшного, если у вас не получилось самостоятельно. Это новый материал. Если вы хотите передать другой заголовок в зависимости от того, какая кнопка была нажата, тело вашего метода prepare(for:sender:)может выглядеть следующим образом:

 

guard let sender = sender as? UIButton else {return}
 
if sender == forgotPasswordButton {
    segue.destination.navigationItem.title = “Forgot Password”
} else if sender == forgotUsernameButton {
    segue.destination.navigationItem.title = “Forgot Username”
} else {
    segue.destination.navigationItem.title = usernameTextField.text
}

 

  • Код выше приводит sender к типу UIButton, что в данном случае всегда успешно. Почему так? Переход входа (login segue) специально вызывается кнопкой, а переход ForgottenUsernameOrPassword вызывается методом performSegue(withIdentifier:sender:), где вы передали соответствующую кнопку в качестве sender. После этого оператор if проверяет, была ли sender кнопкой forgotPasswordButton, и соответственно устанавливает заголовок. Если sender не была кнопкой forgotPasswordButton, другой оператор if проверяет, была ли senderкнопкой forgotUserNameButton, и соответственно устанавливает заголовок. Если sender не была кнопкой forgotPasswordButton, остается только один вариант — когда была нажата кнопка входа, что устанавливает заголовок на имя пользователя.

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

Связь с дизайном

В вашей рабочей тетради по дизайну приложений обдумайте необходимость переходов (segues) и различных видов контроллеров представлений. Понадобятся ли вам навигационные контроллеры для отображения связанного или иерархического контента? Сделайте комментарии в разделе Прототип или на новом пустом слайде в конце документа.

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

 

 

 


Отрывок из книги
Develop in Swift Fundamentals
Apple Education
https://books.apple.com/ru/book/develop-in-swift-fundamentals/id1581182804

 

Information

Apple, the Apple logo, Apple Books, Apple TV, Apple Watch, Cocoa, Cocoa Touch, Finder, Handoff, HealthKit, iPad, iPad Pro, iPhone, iPod touch, Keynote, Mac, macOS, Numbers, Objective-C, Pages, Photo Booth, Safari, Siri, Spotlight, Swift, tvOS, watchOS, and Xcode are trademarks of Apple Inc., registered in the U.S. and other countries. App Store and iBooks Store are service marks of Apple Inc., registered in the U.S. and other countries. ​
The Bluetooth® word mark and logos are registered trademarks owned by Bluetooth SIG, Inc. and any use of such marks by Apple is under license. ​
IOS is a trademark or registered trademark of Cisco in the U.S. and other countries and is used under license. ​
Other product and company names mentioned herein may be trademarks of their respective companies.