UIView анимированные прыжки позиции
У меня есть анимация перехода, когда мне нужно, чтобы казалось, что элемент на VC1 перемещается в новое место, когда VC2 перемещается в положение. У меня не было проблем с выполнением этой работы на других переходах, но для этого у меня есть проблема, которую я не могу решить.
VC1 - имеет изображение в центре с определенным размером VC2 - такое же изображение помещается в верхнем правом углу с меньшим размером
Поэтому мне нужно двигаться и масштабироваться, так как я делаю это на переходном этапе, я подумал, что правильный способ сделать это:
- взять изображение из VC2 translate и масштабировать его так, чтобы оно соответствовало изображению в VC1 (используя transform)
- скрыть изображение на VC1
- одушевленное изображение из VC2 обратно в.identity
Я успешно сделал то же самое, когда переместил что-то в верхний левый угол. Однако, когда я делаю эту конкретную анимацию, я вижу, как мое изображение VC2 прыгает, когда анимация начинается в новом месте. Я вижу этот скачок только тогда, когда я работаю на устройстве / симуляторе, который больше или меньше iPhone7, и он скачет по-разному в зависимости от ширины экрана (слева для меньшего размера, справа для большего).
Я зафиксировал положение своего изображения на всех этапах:
transform from: (x:336.0, y:35.5, w:38.0) to: (x:160.0, y:180.5, w:66.0)
xOffset: -176.0 yOffset: 145.0
transform: CGAffineTransform(a: 1.0, b: 0.0, c: 0.0, d: 1.0, tx: -176.0, ty: 145.0)
preanimation: (x: 160.0, y: 180.5
currentPosition: (midX: 105.0, midY: 180.5)
currentPosition: (midX: 112.312, midY: 174.476)
Первая строка этого журнала показывает, что я перемещаю свое изображение из (336, 35) в (160, 180,5). Вторая строка показывает, что моя математика верна. Третья строка показывает преобразование, которое было создано (масштабирование в настоящее время отключено). Четвертая строка показывает, что мое изображение находится в правильном месте непосредственно перед началом анимации. Последние 2 строки возвращаются в обратном вызове cadisplaylink, показывающем, что моя позиция подскочила до начала анимации.
Кто-нибудь сталкивался с чем-то подобным? Любые подсказки, как я могу решить это? Все мои изображения помещаются в LayoutConstraints, все мои анимации запускаются с использованием преобразований (преобразование перед анимацией, а затем анимация обратно в.identity).
РЕДАКТИРОВАТЬ: Некоторые добавили информацию, при запуске в альбомной ориентации я заметил, что мои оригинальные кадры совершенно не так:
transform from: (x:336.0, y:35.5, w:38.0) to: (x:368.0, y:147.666666666667, w:66.0)
xOffset: 32.0 yOffset: 112.166666666667
transform: CGAffineTransform(a: 2.66666666666667, b: 0.0, c: 0.0, d: 2.66666666666667, tx: 32.0, ty: 112.166666666667)
preanimation: (x: 368.0, y: 147.666666666667
currentPosition: (midX: 729.0, midY: 127.666666666667)
Поэтому на данный момент я думаю, что проблема заключается в том, что мои кадры, с которыми я пытаюсь синхронизироваться, не корректны перед анимацией из-за ограничений автопоставки. И когда анимация начинается, все кадры пересчитываются анимацией с использованием ограничений макета, тогда мои преобразования применяются, чтобы появился переход.
EDIT2:
Я думаю, я понял это. Проблема в том, что представление, в котором я анимирую, еще не выложило свои подпредставления, поэтому кадры отключены. По телефону .setNeedsLayout()
а также .layoutIfNeeded()
на моих взглядах во время настройки анимации я получаю правильные места для анимации между ними.
Для любопытных вот те же журналы из моего первого редактирования с добавлением, когда вызываются методы viewlifecycle:
viewDidLoad <Chalkboard.SwipeToMoveViewController: 0x7fb1f760fb70>
viewWillAppear <Chalkboard.SwipeToMoveViewController: 0x7fb1f760fb70>
transform from: (x:336.0, y:35.5, w:38.0) to: (x:368.0, y:147.666666666667, w:66.0)
xOffset: 32.0 yOffset: 112.166666666667
transform: CGAffineTransform(a: 2.66666666666667, b: 0.0, c: 0.0, d: 2.66666666666667, tx: 32.0, ty: 112.166666666667)
preanimation: (x: 368.0, y: 147.666666666667
animation Block: (to.x: 368.0, to.y: 147.666666666667 - (from.x: 368.0, from.y: 147.666666666667
viewWillLayoutSubviews <Chalkboard.SwipeToMoveViewController: 0x7fb1f760fb70>
viewDidLayoutSubviews <Chalkboard.SwipeToMoveViewController: 0x7fb1f760fb70>
currentPosition: (midX: 729.0, midY: 127.666666666667)
1 ответ
Просто если люди не хотят читать через стену текста, чтобы найти решение проблемы, я использовал положения представлений в разных контроллерах представлений до того, как все представления были разложены. Я предполагал, что весь жизненный цикл представления был обработан в моем контроллере представления до запуска логики анимации, я был не прав.
Порядок вызова анимации:
- viewDidLoad
- viewWillAppear
- animateTransition
- viewWillLayoutSubviews
- viewDidLayoutSubviews
Таким образом, исправление было вручную вызвать setNeedsLayout()
а также layoutIfNeeded()
как начало моего animateTransition, чтобы все позиции моих представлений были известны и могли использоваться для преобразований.