Пользовательские переходы UIViewController Приступая к работе

Пользовательские переходы UIViewController: начало работы.

Это руководство научит вас создавать пользовательские переходы UIViewController для представления и отклонения, а также как сделать их интерактивными.!

Версия.

Swift 4, iOS 11, Xcode 9.

iOS предоставляет несколько удобных переходов контроллера представления — push, pop, cover вертикально — бесплатно, но создавать свои собственные — очень весело. Пользовательские переходы UIViewController могут значительно улучшить взаимодействие с пользователем и выделить ваше приложение среди остальной части пакета. Если вы избегали создания собственных пользовательских переходов, потому что процесс кажется слишком сложным, вы обнаружите, что это не так сложно, как вы могли ожидать..

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

Как устроен переходный API. Как представить и закрыть контроллеры представления с помощью настраиваемых переходов. Как создавать интерактивные переходы.

Начиная.

Загрузите стартовый проект. Скомпилируйте и запустите проект; вы увидите следующую игру в догадки:

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

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

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

Изучение переходного API.

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

Кусочки головоломки.

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

Каждый контроллер представления может иметь transitioningDelegate, объект, соответствующий UIViewControllerTransitioningDelegate. .

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

Контроллер анимации, возвращаемый делегатом перехода, является объектом, реализующим UIViewControllerAnimatedTransitioning. Он выполняет «тяжелую работу» по реализации анимированного перехода..

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

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

Переходный процесс.

Вот шаги, необходимые для перехода между презентациями:

Вы запускаете переход программно или через переход. UIKit запрашивает контроллер представления «кому» (отображаемый контроллер представления) для своего делегата перехода. Если его нет, UIKI использует стандартный встроенный переход. Затем UIKit запрашивает у переходящего делегата контроллер анимации через animationController (forPresenting: presenting: source :). Если это вернет nil, переход будет использовать анимацию по умолчанию. UIKit конструирует переходный контекст. UIKit запрашивает у контроллера анимации продолжительность анимации, вызывая transitionDuration (используя :). UIKit вызывает animateTransition (используя 🙂 на контроллере анимации для выполнения анимации перехода. Наконец, контроллер анимации вызывает completeTransition (_ 🙂 в контексте перехода, чтобы указать, что анимация завершена..

Шаги для отклоняющего перехода практически идентичны. В этом случае UIKit запрашивает у контроллера представления «от» (тот, который отклоняется) о переходящем делегате. Делегат перехода передает соответствующий контроллер анимации через animationController (forDismissed 🙂 .

Создание пользовательского перехода между презентациями.

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

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

Создание аниматора.

Вы начнете с создания контроллера анимации..

В меню выберите File \ New \ File…, выберите iOS \ Source \ Cocoa Touch Class и нажмите Next. Назовите файл FlipPresentAnimationController, сделайте его подклассом NSObject и установите язык Swift. Нажмите «Далее» и установите для группы «Контроллеры анимации». Нажмите "Создать". .

Контроллеры анимации должны соответствовать UIViewControllerAnimatedTransitioning. Откройте FlipPresentAnimationController.swift и соответствующим образом обновите объявление класса..

Xcode вызовет ошибку, сообщая, что FlipPresentAnimationController не соответствует UIViewControllerAnimatedTransitioning. Нажмите Исправить, чтобы добавить необходимые подпрограммы-заглушки..

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

Затем вы должны ввести код для двух добавленных вами заглушек. Обновите transitionDuration (используя 🙂 следующим образом:

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

Добавьте в animateTransition следующее (используя :):

Вот что это делает:

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

Продолжайте добавлять в тело animateTransition (используя 🙂 .

Представление контейнера, созданное UIKit, содержит только представление «от». Вы должны добавить любые другие представления, которые будут участвовать в переходе. Важно помнить, что addSubview (_ 🙂 помещает новое представление впереди всех остальных в иерархии представлений, поэтому порядок, в котором вы добавляете вложенные представления, имеет значение..

Добавьте новое представление «Кому» в иерархию представлений и скройте его. Поместите снимок перед ним. Установите начальное состояние анимации, повернув снимок на 90˚ вокруг оси y. Это приводит к тому, что зритель смотрит на него ребром и, следовательно, не виден, когда начинается анимация. Получить продолжительность анимации.

Теперь у вас все настроено; время оживлять! Завершите метод, добавив следующие.

Вот пошаговая инструкция вашей анимации:

Вы используете стандартную анимацию по ключевым кадрам UIView. Продолжительность анимации должна точно соответствовать длине перехода. Начните с поворота ракурса «из» на 90 its вокруг оси Y, чтобы скрыть его из вида. Затем откройте снимок, повернув его обратно из состояния наведения, которое вы установили выше. Установите рамку снимка на весь экран. Снимок теперь точно соответствует просмотру «до», поэтому теперь можно безопасно отображать реальный вид. Удалите снимок из иерархии представлений, поскольку он больше не нужен. Затем верните вид «из» в исходное состояние; в противном случае он будет скрыт при обратном переходе. Вызов completeTransition (_ 🙂 сообщает UIKit, что анимация завершена. Это обеспечит согласованность конечного состояния и уберет вид «из» из контейнера..

Теперь ваш контроллер анимации готов к использованию!

Подключение аниматора.

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

Откройте CardViewController.swift и добавьте следующее расширение внизу файла.

Здесь вы возвращаете экземпляр своего настраиваемого контроллера анимации, инициализированный кадром текущей карты..

Последний шаг — пометить CardViewController в качестве делегата перехода. Контроллеры представления имеют свойство transitioningDelegate, которое UIKit будет запрашивать, чтобы узнать, следует ли использовать настраиваемый переход..

Добавьте следующее в конец файла prepare (for: sender 🙂 сразу под назначением карты:

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

Создайте и запустите свой проект. Нажмите на карточку, и вы должны увидеть следующее:

И вот он — ваш первый пользовательский переход!

Отключение View Controller.

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

В меню выберите File \ New \ File…, выберите iOS \ Source \ Cocoa Touch Class и нажмите Next. Назовите файл FlipDismissAnimationController, сделайте его подклассом NSObject и установите язык Swift. Нажмите «Далее» и установите для группы «Контроллеры анимации». Нажмите "Создать". .

Замените определение класса следующим.

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

Уменьшите отображаемый вид до размера карты; destinationFrame содержит это значение. Переверните вид, чтобы открыть исходную карту..

Добавьте следующие строки в animateTransition (используя 🙂 .

Пользовательские переходы UIViewController Приступая к работе контроллер представления

Все это должно показаться знакомым. Вот важные отличия:

На этот раз вы должны изменить вид «из», чтобы сделать снимок. Опять же, порядок слоев важен. Сзади к началу они должны быть в следующем порядке: «до», «из», «снимок». Хотя это может показаться неважным в данном конкретном переходе, он жизненно важен для других, особенно если переход можно отменить. Поверните вид «на» так, чтобы он находился под углом, чтобы он не отображался сразу при повороте снимка..

Все, что сейчас нужно, — это сама анимация. Добавьте следующий код в конец animateTransition (используя 🙂 .

Это в точности противоположность представленной анимации..

Сначала уменьшите масштаб снимка, а затем скройте его, повернув на 90˚. Затем откройте вид «на», повернув его назад из положения «с ребра». Очистите ваши изменения в иерархии представлений, удалив моментальный снимок и восстановив состояние представления «из». Если переход был отменен — ​​он пока невозможен для этого перехода, но вы сделаете это возможным в ближайшее время — важно удалить все, что вы добавили в иерархию представлений, прежде чем объявить переход завершенным..

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

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

Больше нет необходимости запускать медленную анимацию презентации. Откройте FlipPresentAnimationController.swift и измените продолжительность с 2,0 на 0,6, чтобы она соответствовала вашей новой анимации увольнения..

Строй и беги. Поиграйте с приложением, чтобы увидеть свои новые модные анимированные переходы.

Делаем это интерактивным.

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

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

Как работают интерактивные переходы.

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

Пользовательские переходы UIViewController Приступая к работе работа

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

В меню выберите File \ New \ File…, выберите iOS \ Source \ Cocoa Touch Class и нажмите Next. Назовите файл SwipeInteractionController, сделайте его подклассом UIPercentDrivenInteractiveTransition и установите язык Swift. Нажмите «Далее» и установите для группы «Контроллеры взаимодействия». Нажмите "Создать". .

Добавьте в класс следующее.

Эти объявления довольно просты.

InteractionInProgress, как следует из названия, указывает, происходит ли уже взаимодействие. shouldCompleteTransition будет использоваться внутри для управления переходом. Вы увидите как скоро. viewController — это ссылка на контроллер представления, к которому прикреплен этот контроллер взаимодействия..

Затем настройте распознаватель жестов, добавив в класс следующий метод.

Распознаватель жестов настроен на срабатывание, когда пользователь проводит от левого края экрана и добавляется в представление..

Последняя часть контроллера взаимодействия — handleGesture (_ :). Добавьте это в класс сейчас.

Вот пошаговая инструкция:

Вы начинаете с объявления локальных переменных для отслеживания прогресса смахивания. Вы выбираете перевод в представлении и подсчитываете прогресс. Для завершения перехода будет считаться достаточно смахивания 200 или более точек. При запуске жеста вы устанавливаете для InteractionInProgress значение true и запускаете увольнение контроллера представления. Пока жест движется, вы постоянно вызываете update (_ :). Это метод в UIPercentDrivenInteractiveTransition, который перемещает переход на процентное значение, которое вы передаете. Если жест отменен, вы обновляете интерактивностьInProgress и откатываете переход. После завершения жеста вы используете текущий прогресс перехода, чтобы решить, отменить () его или завершить () для пользователя..

Теперь вы должны добавить сантехнику, чтобы создать свой SwipeInteractionController. Откройте RevealViewController.swift и добавьте следующее свойство.

Затем добавьте следующее в конец viewDidLoad () .

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

Откройте FlipDismissAnimationController.swift и добавьте следующее свойство после объявления для destinationFrame .

Замените init (destinationFrame 🙂 на:

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

Откройте CardViewController.swift и замените animationController (forDismissed 🙂 на:

Это просто обновляет создание FlipDismissAnimationController в соответствии с новым инициализатором..

Наконец, UIKit запрашивает у переходящего делегата контроллер взаимодействия, вызывая InteractionControllerForDismissal (используя :). Добавьте следующий метод в конец расширения UIViewControllerTransitioningDelegate.

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

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

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

Куда пойти отсюда?

Вы можете скачать готовый проект для этого руководства здесь.

Чтобы узнать больше о типах анимации, которые вы можете делать, ознакомьтесь с Главой 17, «Контроллер презентаций. & Ориентационные анимации »в iOS Animations по учебным пособиям.

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

При использовании контроллера навигации за продажу контроллеров анимации отвечает его делегат, который является объектом, соответствующим UINavigationControllerDelegate. Делегат может предоставить контроллер анимации в navigationController (_: animationControllerFor: from: to :). Контроллер панели вкладок полагается на объект, реализующий UITabBarControllerDelegate для возврата контроллера анимации в tabBarController (_: animationControllerForTransitionFrom: to 🙂 .

Надеюсь, вам понравился этот урок. Если у вас есть какие-либо вопросы или комментарии, присоединяйтесь к обсуждению на форуме ниже!

Похожие статьи