Как мне оживить позицию CALayer? - PullRequest
0 голосов
/ 15 ноября 2018

Пожалуйста, обратите внимание на следующий метод, который я использую для перемещения подслоя на 50 точек вверх по оси Y.В частности, обратите внимание на последнюю строку (которая закомментирована).

@objc func animateButtonPressed(_ sender: UIButton) {
    let initialValue = customView.sublayer.position.y
    let finalValue = customView.sublayer.position.y - 50

    let animation = CABasicAnimation(keyPath: "position.y")
    animation.fromValue = initialValue
    animation.toValue = finalValue
    animation.duration = 2
    customView.sublayer.add(animation, forKey: "Reposition")

    //customView.sublayer.position.y = finalValue
}

С кодом, как показано, я получаю следующее поведение:

  1. Слой медленно перемещаетсяиз начальной позиции в конечную позицию.
  2. Затем слой возвращается в исходную позицию.
  3. Слой остается в начальной позиции.

Все, что яread сообщает мне, что «прыжок назад» происходит, потому что я не обновил модель, чтобы отразить окончательное значение.Итак, давайте обновим модель, раскомментировав последнюю строку.Теперь поведение таково:

  1. Слой переходит с начальной позиции на конечную.
  2. Затем слой переходит обратно к начальной позиции.
  3. Слойзатем медленно перемещается в конечную позицию.
  4. Слой остается в конечной позиции.

По-видимому, происходит скачок, поскольку в модели устанавливается конечная позиция.Я чувствую, что я в ловушке 22. Любая помощь будет высоко ценится.

Рабочий проект, который иллюстрирует проблему, можно найти на GitHub

Xcode 10.0,iOS 12.2, Swift 4.2

1 Ответ

0 голосов
/ 15 ноября 2018

Вот каноническая форма, разработанная и объясненная в моей книге.Установите для анимированного слоя конечное значение заранее , но с отключенной неявной анимацией, например:

@objc func animateButtonPressed(_ sender: UIButton) {
    let initialValue = customView.sublayer.position.y
    let finalValue = customView.sublayer.position.y - 50
    CATransaction.setDisableActions(true) //       <-- *
    customView.sublayer.position.y = finalValue // <-- *
    let animation = CABasicAnimation(keyPath: "position.y")
    animation.fromValue = initialValue
    animation.toValue = finalValue
    animation.duration = 2
    customView.sublayer.add(animation, forKey: "Reposition")
}
...