Я реализовал класс LoadLayer, который имеет некоторые анимирующие элементы (2, если быть точным), которые анимируются с CABasicAnimation
. Теперь этот экран загрузочного экрана сохраняется во всем приложении. Скрывает ли представление все анимации? Или позвольте мне перефразировать это: есть ли много памяти, о которой я должен беспокоиться, или может это потенциально вызвать отставание? Я попытался использовать методы -pauseLayer:
и -resumeLayer:
, но они вызвали некоторые проблемы из-за многопоточности в моем приложении. Так ли это просто скрыть и показать экран загрузки с его анимацией, работающей все время?Приостановить и возобновить CABasicAnimation для загрузки экрана?
ответ
https://developer.apple.com/library/content/qa/qa1673/_index.html
-(void)pauseLayer:(CALayer*)layer
{
CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];
layer.speed = 0.0;
layer.timeOffset = pausedTime;
}
-(void)resumeLayer:(CALayer*)layer
{
CFTimeInterval pausedTime = [layer timeOffset];
layer.speed = 1.0;
layer.timeOffset = 0.0;
layer.beginTime = 0.0;
CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
layer.beginTime = timeSincePause;
}
Если представление скрыто (невидимый или нет в интерфейсе вообще), тогда она не является частью дерева отображения.
Но почему бы просто не остановить анимацию, когда контроллер вида, в представлении которого этот слой встроен, покидает интерфейс (viewDidDisappear
)? Просто скажите слою removeAllAnimations
. Затем создайте анимацию заново, если хотите, в viewWillAppear
?
Вот оперативная версия Nico's.
Надежды помогают!
fileprivate func pauseLayer(layer: CALayer) {
let pausedTime = layer.convertTime(CACurrentMediaTime(), from: nil)
layer.speed = 0.0
layer.timeOffset = pausedTime
}
fileprivate func resumeLayer(layer: CALayer) {
let pausedTime = layer.timeOffset
layer.speed = 1.0
layer.timeOffset = 0.0
layer.beginTime = 0.0
let timeSincePause = layer.convertTime(CACurrentMediaTime(), from: nil) - pausedTime
layer.beginTime = timeSincePause
}
Расширение Nico «s ответ на изменение скорости любой переменной:
extension CALayer {
func udpate(speed newSpeed: Float) {
let newSpeed = newSpeed == 0 ? 1e-6 : newSpeed
let triggerTime = self.convertTime(CACurrentMediaTime(), from: nil)
let offset = self.timeOffset
let begin = self.beginTime
let speed = self.speed
self.beginTime = (triggerTime - offset)/Double(speed) + begin
self.timeOffset = triggerTime
self.speed = newSpeed
}
}
использовать этот подход, если вы готовы изменить скорость анимации слоя в интерактивном режиме. Если вы хотите, чтобы полностью остановить слой, вы должны использовать ответ Нико, хотя использование этого метода с speed=0.0
будет на самом деле занимает около 11 дней для анимации, чтобы закончить, и в 1час анимации будет прогрессировать о 0.0036
У меня был очень похож но твоя работа, спасибо! –
Хорошо, нет, на самом деле у меня была такая же реализация. Но теперь я знаю, почему он переставал работать время от времени. Всякий раз, когда приложение переходит в фоновый режим, и я перезапускаю его, анимация не возобновляется снова. Любая идея, что может быть причиной этого? –
попробуйте очистить анимацию и прочитать их на didBeomceActive – Nico