Intereting Posts
Загрузка игрового центра iOS WebSQL – сохранение и извлечение базы данных с SD-карты – PhoneGap iOS Как отправить AudioBuffer через QuickBlox error: Void method 'undo:' не должен возвращать значение Загрузка сохраненного изображения из каталога документов проблема с пониманием Obj-C MVC: exit and unwindSegue У приложений, использующих iOS Social Framework, влияют ограничения по скорости Twitter? Как загрузить вторую вкладку в UITabBarcontroller нажатием кнопки .. ?? Как изменить расположение моей кнопки местоположения на картах Google с помощью быстрой Ошибка C ++ Нет соответствующей функции-члена для вызова addtoucheventlistener cocoalibspotify: сбой во время обратного вызова воспроизведения в формате music_delivery Зарегистрировать нового пользователя в firebase AVCaptureSession дает увеличенный результат Метод WCF GET не получает последние данные для iOS Client Geofencing в iOS Когда приложение закрыто / убито

Непредсказуемое поведение с Core Animation (CABasicAnimation)

Я писал строку анимации для iOS, где линия нарисована на CALayer как набор точек в CGPath. Линия анимируется от плоского положения до «формованной» формы с разными координатами y, но всегда одна и та же координата x похожа на анимацию линейной диаграммы.

Чтобы упростить точечную интерполяцию, я добавил собственное свойство CGFloat в мой подкласс CALayer. Я называю это свойство «аниматором» (лучшим именем может быть прогресс, интерполятор и т. Д.). Идея заключалась в том, чтобы добавить простую CABasicAnimation по этому свойству от 0.0f до 1.0f таким образом, я получаю возможность использования функции синхронизации и интерполяции Core Animation во время все еще имея возможность легко писать пользовательские анимации. Например, если точка линии должна перейти от y = 100 к y = 130, то когда аниматор равен 0.0f, я нахожусь в состоянии 100, когда его 1.0f, то я нахожусь в точке 130, промежуточные значения дают мне мои промежуточные точки, а я продолжайте рисовать линию с этими новыми точками, чтобы получить мою анимацию.

Теперь анимация работает отлично, я отключил действия на уровне, добавил needsDisplayForKey и т. Д., Но моя проблема в Core Animation неточна. Конечное значение аниматора иногда составляет 0,95 0,96 и т. Д., А не 1,0. Хорошо, что это нормально, поскольку числа с плавающей запятой имеют проблемы с точностью, однако, когда значение моей модели обновляется (устанавливается на 1.0f перед добавлением анимации на уровень), линия должна повторно рисовать, и я должен получить точный визуал.

Здесь возникает другая проблема. Иногда анимация не удаляется немедленно. В большинстве случаев он мгновенно удаляется, и у меня нет проблем, но иногда он остается включенным в течение нескольких секунд, иногда даже минут. Чтобы проверить мою теорию о том, что анимация не удаляется, я добавил к моему слою простой флаг BOOL, который возвращает YES, когда мы находимся на уровне представления, и, конечно же, иногда я вижу, что мой последний вызов drawInContext находился на уровне презентации с величиной аниматора 0.98967f или что-то еще, и окончательный вызов drawInContext с аниматором 1.0f, а флаг уровня представления – NO, происходит намного позже. В результате мои визуальные прыжки и не точно отличаются от очевидного ужасного пользовательского опыта.

Я попытался объяснить свою проблему как можно лучше, если бы кто-то захотел увидеть код, я был бы рад предоставить свой тестовый проект. Здесь надеется, что какой-то умный человек увидит это и сможет мне помочь.

edit 1: Загрузили весь проект Xcode (включая мои неприятные изменения, чтобы показать, что все, что я пробовал) здесь .

edit 2: кто-то с аналогичной проблемой, который вручную удаляет анимацию по завершении http://lucas.tiz.ma/blog/2012/04/18/core-animation-is-a-bit-garbage-collection-y/

Благодарю.

tl; dr Явно вызовите setNeedsDisplay в анимацииDidStop: завершено: делегировать вызов.

Согласно сообщению Lucas Tizma (см. Изменение 2 выше), я попытался удалить анимацию вручную. Я выбрал более простой подход, чем его базовый блок, установив слои в качестве делегатов анимаций, установленных на них. Таким образом, начало и конец обратного вызова анимации поступают непосредственно на соответствующий слой. Ну явно явное удаление анимаций в анимацииDidStop: завершено: обратный вызов не устраняет проблему. Например, иногда (см. Журнал ниже, особенно временные метки) анимация останавливается и проверка того, что она удалена, показывает, что она была удалена, однако точная ничья с фактическим значением модели происходит намного позже.

// animationDidStop:finished: call back code NSLog(@"layer animation stopped"); // check if any animations exist NSLog(@"animation keys: %@", [self animationKeys]); // remove animations and check NSLog(@"removing animations"); [self removeAllAnimations]; NSLog(@"animation keys: %@", [self animationKeys]); // log 2012-10-11 11:47:16.774 ASPathAnimationTest[3017:c07] on presentation layer 1 2012-10-11 11:47:16.774 ASPathAnimationTest[3017:c07] 335 animation draw update, animator is 0.982606 2012-10-11 11:47:16.775 ASPathAnimationTest[3017:c07] startPoint: {100, 90} - endPoint: {100, 100} - newPoint: {100, 99.8261} <snip> 2012-10-11 11:47:16.791 ASPathAnimationTest[3017:c07] startPoint: {1000, 50} - endPoint: {1000, 100} - newPoint: {1000, 99.1303} 2012-10-11 11:47:16.792 ASPathAnimationTest[3017:c07] layer animation stopped 2012-10-11 11:47:16.792 ASPathAnimationTest[3017:c07] animation keys: (null) 2012-10-11 11:47:16.793 ASPathAnimationTest[3017:c07] removing animations 2012-10-11 11:47:16.793 ASPathAnimationTest[3017:c07] animation keys: (null) 2012-10-11 11:47:16.794 ASPathAnimationTest[3017:c07] layer animation stopped 2012-10-11 11:47:16.794 ASPathAnimationTest[3017:c07] animation keys: (null) 2012-10-11 11:47:16.794 ASPathAnimationTest[3017:c07] removing animations 2012-10-11 11:47:16.795 ASPathAnimationTest[3017:c07] animation keys: (null) 2012-10-11 11:47:16.795 ASPathAnimationTest[3017:c07] layer animation stopped 2012-10-11 11:47:16.819 ASPathAnimationTest[3017:c07] animation keys: (null) 2012-10-11 11:47:16.820 ASPathAnimationTest[3017:c07] removing animations 2012-10-11 11:47:16.820 ASPathAnimationTest[3017:c07] animation keys: (null) 2012-10-11 11:47:16.821 ASPathAnimationTest[3017:c07] layer animation stopped 2012-10-11 11:47:16.821 ASPathAnimationTest[3017:c07] animation keys: (null) 2012-10-11 11:47:16.821 ASPathAnimationTest[3017:c07] removing animations 2012-10-11 11:47:16.822 ASPathAnimationTest[3017:c07] animation keys: (null) 2012-10-11 11:47:16.822 ASPathAnimationTest[3017:c07] layer animation stopped 2012-10-11 11:47:16.822 ASPathAnimationTest[3017:c07] animation keys: (null) 2012-10-11 11:47:16.823 ASPathAnimationTest[3017:c07] removing animations 2012-10-11 11:47:16.823 ASPathAnimationTest[3017:c07] animation keys: (null) 2012-10-11 11:48:00.000 ASPathAnimationTest[3017:c07] on presentation layer 0 2012-10-11 11:48:00.000 ASPathAnimationTest[3017:c07] 336 animation draw update, animator is 1.000000 <snip, there are 5 lines so draw and point logs go here> 2012-10-11 11:48:00.021 ASPathAnimationTest[3017:c07] 340 animation draw update, animator is 1.000000 2012-10-11 11:48:00.023 ASPathAnimationTest[3017:c07] startPoint: {100, 90} - endPoint: {100, 100} - newPoint: {100, 100} <snip> 2012-10-11 11:48:00.026 ASPathAnimationTest[3017:c07] startPoint: {1000, 50} - endPoint: {1000, 100} - newPoint: {1000, 100} 

После просмотра журнала и замечания факта, что анимация действительно удаляется, просто повторная ничья с фактическим точным значением модели иногда не происходит до тех пор, пока секунды или даже минуты позже я не изменил анимациюDidStop: завершено: делегировать вызов для явного вызова setNeedsDisplay на слое. Бинго.