Как получить текущие координаты анимируемого UIView во время анимации?

«Как получить текущие координаты анимируемого UIView во время анимации?» — вопрос из категории UIKit, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Во время выполнения Core Animation можно получить текущие, видимые на экране значения свойств слоя через его презентационный слой (presentation layer).

Как это работает: Пока анимация выполняется, система создает и обновляет специальный объект presentationLayer, который отражает текущее состояние анимируемых свойств для рендеринга.

Пример с анимацией позиции:

// 1. Создаем и настраиваем анимацию
let animation = CABasicAnimation(keyPath: "position")
animation.fromValue = CGPoint(x: 50, y: 50)
animation.toValue = CGPoint(x: 200, y: 200)
animation.duration = 2.0
animation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)

// 2. Добавляем анимацию к слою
myView.layer.add(animation, forKey: "movingAnimation")

// 3. НЕМЕДЛЕННО после добавления анимации:
// Модельный слой (model layer) уже имеет конечные значения
print(myView.layer.position) // (200.0, 200.0)

// 4. Получаем текущие координаты из презентационного слоя:
if let presentationFrame = myView.layer.presentation()?.frame {
    print("Current on-screen frame: (presentationFrame)")
}
// Во время анимации будет выводить промежуточные значения, например:
// Current on-screen frame: (80.0, 95.5)

Критически важные нюансы:

  • presentation() возвращает nil, если для слоя в данный момент нет активных анимаций.
  • Для UIView-анимаций (блок UIView.animate) также можно использовать view.layer.presentation().
  • Презентационный слой обновляется с частотой кадров и предназначен только для чтения. Изменять его свойства бесполезно.
  • Для плавного получения значений (например, в интерактивной анимации) используйте CADisplayLink или свойства UIViewPropertyAnimator (для iOS 10+).