У меня есть приложение на основе навигации, и я хочу изменить анимацию анимации push и pop. Как бы я это сделал?
Изменить 2018
Было много ответов на этот вопрос, и прошло уже довольно много времени, я снова выбрал ответ на то, что я считаю наиболее актуальным сейчас. Если есть кто-то, кто думает иначе, пожалуйста, дайте мне знать в комментариях
ios
animation
uinavigationcontroller
прививка
источник
источник
Ответы:
Для 2019 года "окончательный ответ!"
Преамбула:
Скажем, вы новичок в разработке для iOS. Смущает, что Apple предоставляет два перехода, которые можно легко использовать. Это: «кроссфейд» и «флип».
Но, конечно, «кроссфейд» и «флип» бесполезны. Они никогда не используются. Никто не знает, почему Apple предоставила эти два бесполезных перехода!
Так:
Скажем, вы хотите сделать обычный, обычный переход, такой как «слайд». В этом случае вам придется выполнить ОГРОМНОЕ количество работы! ,
Эта работа, объясняется в этом посте.
Просто повторить:
Удивительно: с iOS, если вам нужны самые простые, самые обычные, ежедневные переходы (например, обычный слайд), вам придется выполнить всю работу по реализации полного пользовательского перехода .
Вот как это сделать ...
1. Вам нужен кастом
UIViewControllerAnimatedTransitioning
Вы нуждаетесь в bool своего собственного как
popStyle
. (Это срабатывает, или выключается?)Вы должны включить
transitionDuration
(тривиально) и основной вызов,animateTransition
На самом деле вы должны написать две разные процедуры для внутри
animateTransition
. Один для толчка, а другой для попса. Наверное, назовите ихanimatePush
иanimatePop
. ВнутриanimateTransition
просто переходитеpopStyle
к двум подпрограммамВ приведенном ниже примере выполняется простое перемещение / удаление
По твоему
animatePush
иanimatePop
рутине. Вы должны получить «от просмотра» и «для просмотра». (Как это сделать, показано в примере кода.)и вы должны
addSubview
для нового "чтобы" посмотреть.и вы должны позвонить
completeTransition
в конце вашего анимеТак ..
А потом ...
2. Используйте его в вашем контроллере представления.
Примечание: как ни странно, вам нужно сделать это только в «первом» контроллере представления. (Тот, который "под".)
С тем, что вы попали на вершине , ничего не делать . Легко.
Итак, ваш класс ...
становится ...
Вот и все.
Толчок и треск точно так же, как обычно, без изменений. Толкать ...
и выложить его, если хотите, просто сделайте это на следующем экране:
Уф.
3. Также воспользуйтесь другими ответами на этой странице, которые объясняют, как переопределить AnimatedTransitioning.
Перейдите к @AlanZeino и ответу @elias, чтобы обсудить, как сделать это
AnimatedTransitioning
в приложениях для iOS в эти дни!источник
animatePush
иanimatePop
есть .. два разных направления!Я сделал следующее, и это работает нормально .. и это просто и легко понять ..
И то же самое для толчка ..
Версия Swift 3.0:
источник
Animated:NO
это жизненно важно. ЕслиYES
оно пропущено, анимация смешивается и вызывает забавные эффекты.setViewControllers:
Так мне всегда удавалось выполнить эту задачу.
Для толчка:
Для поп:
Я все еще получаю много отзывов об этом, поэтому я собираюсь продолжить и обновлять его, чтобы использовать блоки анимации, что в любом случае является рекомендованным Apple способом создания анимации.
Для толчка:
Для поп:
источник
super
наself.navigationController
UIViewController
подклассу имя без части "ViewController". Это имя больше подходит для UIView.для толчка
для поп
источник
@Magnus ответ, только тогда для Swift (2.0)
Некоторые sidenotes:
Вы можете сделать это также с Segue, просто внедрите это в
prepareForSegue
илиshouldPerformSegueWithIdentifier
. Тем не менее , это также сохранит анимацию по умолчанию. Чтобы это исправить, вам нужно перейти на раскадровку, нажать «Segue» и снять флажок «Animates». Но это ограничит ваше приложение для IOS 9.0 и выше (по крайней мере, когда я сделал это в Xcode 7).При выполнении последующих двух строк следует заменить на:
Даже если я установил значение false, это как бы игнорирует это.
источник
Помните, что в Swift , расширение определенно ваши друзья!
источник
Использование личных звонков - плохая идея, так как Apple больше не одобряет приложения, которые делают это. Может быть, вы могли бы попробовать это:
источник
-pushViewController:transition:forceImmediate:
которая была бы плохой идеей.Так как это лучший результат в Google, я решил поделиться тем, что я считаю самым разумным способом; который должен использовать API перехода iOS 7+. Я реализовал это для iOS 10 с Swift 3.
Довольно просто объединить это с
UINavigationController
анимацией между двумя контроллерами представления, если вы создаете подклассUINavigationController
и возвращаете экземпляр класса, который соответствуетUIViewControllerAnimatedTransitioning
протоколу.Например вот мой
UINavigationController
подкласс:Вы можете видеть, что я установил
UINavigationControllerDelegate
для себя, и в расширении моего подкласса я реализую метод,UINavigationControllerDelegate
который позволяет вам возвращать пользовательский контроллер анимации (то есть,NavigationControllerAnimation
). Этот пользовательский контроллер анимации заменит вам стандартную анимацию.Вы, наверное, удивляетесь, почему я передаю операцию
NavigationControllerAnimation
экземпляру через его инициализатор. Я делаю это так, чтобы вNavigationControllerAnimation
реализацииUIViewControllerAnimatedTransitioning
протокола я знал, что это за операция (т. Е. «Push» или «pop»). Это помогает узнать, какую анимацию я должен делать. Большую часть времени вы хотите выполнить другую анимацию в зависимости от операции.Остальное довольно стандартно. Реализуйте две необходимые функции в
UIViewControllerAnimatedTransitioning
протоколе и анимируйте, как вам нравится:Важно помнить, что для каждого отдельного типа операции (т. Е. «Push» или «pop») контроллеры представления «в» и «из» будут разными. Когда вы выполняете операцию нажатия, контроллером для просмотра будет тот, который будет выдвинут. Когда вы работаете в режиме pop, контроллер для просмотра будет тем, к которому осуществляется переход, и контроллером из представления будет тот, который выскочил.
Кроме того,
to
контроллер представления должен быть добавлен как подпредставлениеcontainerView
в контексте перехода.Когда ваша анимация завершится, вы должны позвонить
transitionContext.completeTransition(true)
. Если вы делаете интерактивный переход, вам придется динамически возвращать aBool
вcompleteTransition(didComplete: Bool)
зависимости от того, завершен ли переход в конце анимации.Наконец ( необязательно чтение ), вы можете посмотреть, как я сделал переход, над которым я работал. Этот код немного более хакерский, и я написал его довольно быстро, поэтому я бы не сказал, что это отличный анимационный код, но он все еще показывает, как выполнять анимационную часть.
Мой был действительно простой переход; Я хотел имитировать ту же анимацию, что обычно делает UINavigationController, но вместо анимации «следующая страница поверх», я хотел реализовать анимацию 1: 1 старого контроллера представления одновременно с новым видом контроллер появляется. Это приводит к тому, что два контроллера представления выглядят так, как будто они прикреплены друг к другу.
Для операции push, которая требует сначала установить начало
toViewController
координат вида на экране выключения оси x, добавить его в качестве подпредставленияcontainerView
, анимировать его на экране, установив егоorigin.x
на ноль. В то же время я анимируюfromViewController
изображение,origin.x
отключив его от экрана:Поп-операция в основном обратная. Добавьте
toViewController
как подпредставлениеcontainerView
и анимируйтеfromViewController
справа, как вы анимируетеtoViewController
слева:Вот суть всего файла swift:
https://gist.github.com/alanzeino/603293f9da5cd0b7f6b60dc20bc766be
источник
Есть UINavigationControllerDelegate и UIViewControllerAnimatedTransitioning, где вы можете изменить анимацию для чего угодно.
Например, это вертикальная поп-анимация для VC:
}
А потом
Полезный учебник https://www.objc.io/issues/5-ios7/view-controller-transitions/
источник
На основании ответа, обновленного для swift 4
jordanperry
Для толчка
UIViewController
Для поп
источник
Вот как я сделал то же самое в Swift:
Для толчка:
Для поп:
На самом деле я сделал это немного иначе, чем некоторые из приведенных выше ответов, но, поскольку я новичок в разработке Swift, это может быть неправильно. Я переопределил
viewWillDisappear:animated:
и добавил туда поп-код:источник
@Лука Давандзо ответ в Swift 4.2
источник
Я недавно пытался сделать что-то подобное. Я решил, что мне не нравится скользящая анимация UINavigationController, но я также не хотел делать анимации, которые UIView дает вам, как скручивание или что-то в этом роде. Я хотел сделать перекрестное затухание между видами, когда я нажимаю или щелкаю.
Проблема заключается в том, что представление буквально удаляет представление или накладывает его поверх текущего, поэтому исчезновение не работает. Решение, к которому я пришел, заключалось в том, чтобы взять новое представление и добавить его в качестве подпредставления к текущему виду сверху в стеке UIViewController. Я добавляю его с альфа 0, затем делаю кроссфейд. Когда последовательность анимации заканчивается, я помещаю представление в стек без его анимации. Затем я возвращаюсь к старому topView и очищаю вещи, которые я изменил.
Это немного сложнее, потому что у вас есть навигационные элементы, которые вы должны настроить, чтобы переход выглядел правильно. Кроме того, если вы делаете какое-либо вращение, вам нужно будет отрегулировать размеры кадра при добавлении видов в качестве подпредставлений, чтобы они правильно отображались на экране. Вот часть кода, который я использовал. Я подклассифицировал UINavigationController и переопределил методы push и pop.
Как я уже упоминал в коде, у меня всегда есть элемент кнопки левой панели, поэтому я не проверяю, равен ли он нулю, прежде чем помещать его в массив, который я передаю в качестве контекста для делегата анимации. Если вы сделаете это, вы можете сделать эту проверку.
Проблема, которую я обнаружил, заключалась в том, что, если вы вообще аварийно завершите работу в методе делегата, это не приведет к аварийному завершению программы. Это просто останавливает делегата от завершения, но вы не получаете никакого предупреждения.
Так что, поскольку я выполнял очистку в той процедуре делегата, это вызывало странное визуальное поведение, так как он не заканчивал очистку.
Кнопка «Назад», которую я создаю, вызывает метод «goBack», и этот метод просто вызывает процедуру pop.
Кроме того, вот моя популярная рутина.
Вот и все. Вам понадобится дополнительный код, если вы хотите реализовать ротацию. Вам нужно будет установить размер кадра ваших представлений, которые вы добавляете как подпредставления, прежде чем показывать их, иначе вы столкнетесь с проблемами ориентации в альбомной ориентации, но в последний раз, когда вы видели предыдущий вид, это был портрет. Итак, затем вы добавляете его как вспомогательное представление и затемняете его, но оно отображается как портрет, а затем, когда мы выдвигаемся без анимации, то же самое представление, но то, которое находится в стеке, теперь является альбомным. Все выглядит немного странно. Реализация ротации у всех немного отличается, поэтому я не включил здесь свой код.
Надеюсь, это поможет некоторым людям. Я искал что-то вроде этого и не мог ничего найти. Я не думаю, что это идеальный ответ, но на данный момент он работает очень хорошо для меня.
источник
Теперь вы можете использовать
UIView.transition
. Обратите внимание, чтоanimated:false
. Это работает с любой опцией перехода, pop, push или заменой стека.источник
Используя ответ iJordan в качестве вдохновения, почему бы просто не создать категорию на UINavigationController для использования в вашем приложении вместо копирования / вставки этого кода анимации повсюду?
UINavigationController + animation.h
UINavigationController + Animation.m
Затем просто импортируйте файл UINavigationController + Animation.h и вызовите его как обычно:
источник
Это очень просто
источник
Посмотрите на ADTransitionController , каплю замены UINavigationController с пользовательскими анимациями перехода (его API соответствует API UINavigationController), который мы создали в Applidium.
Вы можете использовать различные предопределенные анимации для push и pop действий, таких как Swipe , Fade , Cube , Carrousel , Zoom и так далее.
источник
Хотя все ответы здесь замечательные и большинство работают очень хорошо, есть немного более простой метод, который достигает того же эффекта ...
Для толчка:
Для поп:
источник
Я не знаю, как можно публично изменить анимацию перехода.
Если кнопка «назад» не нужна, вы должны использовать модальные контроллеры вида, чтобы переходы «сдвиг снизу» / «перевернуть» / «исчезнуть» / (≥3.2) «скручивание страницы».
С частной стороны, метод
-pushViewController:animated:
вызывает недокументированный метод-pushViewController:transition:forceImmediate:
, так что, например, если вы хотите переход с переворота слева направо, вы можете использоватьОднако, вы не можете изменить «поп» переход.
источник
Посмотрите мой ответ на этот вопрос, чтобы узнать, как сделать это в гораздо меньшем количестве строк кода. Этот метод позволяет вам анимировать псевдо-«Push» нового контроллера представления любым удобным вам способом, и когда анимация завершена, он устанавливает Navigation Controller так же, как если бы вы использовали стандартный метод Push. Мой пример позволяет анимировать слайд слева или справа. Код повторяется здесь для удобства:
источник
Из примера приложения, проверьте этот вариант. https://github.com/mpospese/MPFoldTransition/
источник
Просто используйте:
источник
Понимая, что это старый вопрос. Я все еще хотел бы опубликовать этот ответ, так как у меня возникли некоторые проблемы
viewControllers
с предложенными ответами. Мое решение состоит в том, чтобы создать подклассUINavigationController
и переопределить все методы pop и push.FlippingNavigationController.h
FlippingNavigationController.m:
источник
Я знаю, что эта ветка старая, но я решил поставить свои два цента. Вам не нужно создавать собственную анимацию, есть простой (возможно, хакерский) способ сделать это. Вместо использования push создайте новый контроллер навигации, сделайте новый контроллер представления корневым контроллером представления этого контроллера nav, а затем представьте контроллер nav из исходного контроллера nav. Подарок легко настраивается со многими стилями, и нет необходимости создавать собственную анимацию.
Например:
И вы можете изменить стиль презентации, как вы хотите.
источник
Я нашел слегка рекурсивный способ сделать это, который работает для моих целей. У меня есть переменная экземпляра BOOL, которую я использую, чтобы заблокировать обычную анимацию всплывающих окон и заменить свое собственное неанимированное поп-сообщение. Переменная изначально установлена на NO. При нажатии кнопки «Назад» метод делегата устанавливает для него значение «YES» и отправляет новое не анимированное всплывающее сообщение на панель навигации, тем самым снова вызывая тот же метод делегата, на этот раз с переменной, установленной в «YES». Если для переменной задано значение YES, метод делегата устанавливает для него значение NO и возвращает YES, чтобы разрешить появление неанимированного всплывающего окна. После второго вызова делегата мы возвращаемся к первому, где возвращается NO, блокируя оригинальную анимацию! Это на самом деле не так грязно, как кажется. Мой метод shouldPopItem выглядит следующим образом:
Работает для меня.
источник