Допустим, у меня есть аниматор, который перемещает вид с (0, 0)
на (-120, 0)
:
let frameAnimator = UIViewPropertyAnimator(duration: duration, dampingRatio: 0.8)
animator.addAnimations {
switch state:
case .normal: view.frame.origin.x = 0
case .swiped: view.frame.origin.x = -120
}
}
Я использую его вместе с UIPanGestureRecognizer
, так что я могу непрерывно изменять размер представления вместе с движения пальцев.
Проблема возникает, когда я хочу добавить какой-то эффект отскакивания в начале или в конце анимации. НЕ просто коэффициент демпфирования, а эффект отскока. Самым простым способом представить это является функция «Swipe-To-Delete» UITableViewCell
, где вы можете перетащить кнопку «Удалить» за пределы ее фактической ширины, а затем она возвращается назад.
Эффективно то, чего я хочу достичь, это способ установить свойство fractionComplete
вне сегмента [0, 1]
, поэтому, когда дробь равна 1.2
, смещение становится 144
вместо его максимального значения 120.
И сейчас максимальное значение для fractionComplete
в точности равно 1
.
Ниже приведены несколько примеров для визуализации этой проблемы:
То, что у меня сейчас есть:
Чего я хочу достичь:
РЕДАКТИРОВАТЬ (19 января):
Извините за задержку с ответом. Вот некоторые пояснения:
Я не использую UIView.animate(...)
, и вместо этого использую UIViewPropertyAnimator
по очень конкретной причине: c: он обрабатывает все тайминги, кривые и скорости.
Например, вы перетащили вид на полпути. Это означает, что продолжительность оставшейся части должна быть в два раза меньше общей продолжительности. Или, если вы перетащили через 99% расстояния, оставшаяся часть должна пройти почти мгновенно.
Кроме того, UIViewPropertyAnimator
имеет такие функции, как пауза (когда пользователь начинает перетаскивание еще раз) или обратный ход. (когда пользователь начал перетаскивать влево, но после этого он передумал и переместил палец вправо), от чего я тоже выиграю.
Все это недоступно для простых анимаций UIView или требует TONS усилия в лучшем случае. Он допускает только простые переходы, и это не так.
Вот почему я должен использовать какой-то аниматор.
И, как я упоминал в поток комментариев в ответе, который был удален его издателем, самая сложная часть для меня здесь состоит в том, чтобы симулировать эффект трения: чем дальше вы перетаскиваете, тем меньше фактически перемещается представление. Точно так же, как когда вы пытаетесь перетащить любой UIScrollView за пределы его содержимого.
Спасибо за ваши усилия, ребята, но я не думаю, что какой-либо из этих 2 ответов уместен. Я постараюсь реализовать это поведение, используя UIDynamicAnimator
всякий раз, когда у меня есть время. Вероятно, в ближайшие неделю или две. Я опубликую sh мой подход на случай, если у меня будут хорошие результаты.
РЕДАКТИРОВАТЬ (20 января):
Я только что загрузил демонстрационный проект в GitHub, который включает в себя все переходы, которые у меня есть в моем проекте. Так что теперь у вас есть идея, зачем мне нужно для использования аниматоров и как я их использую: https://github.com/demon9733/bouncingview-prototype
Единственный файл, который вас действительно интересует это MainViewController+Modes.swift
. Здесь содержится все, что связано с переходами и анимацией.
Что мне нужно сделать, так это дать пользователю возможность перетаскивать область ручки за пределы ширины кнопки «Скрыть» с эффектом демпфирования. Кнопка «Скрыть» появится при перемещении области маркера влево.
PS Я не тестировал эту демонстрацию, поэтому в ней могут быть ошибки, которых нет в моем основном проекте. Так что вы можете спокойно их игнорировать.