Неправильная анимация с ограничениями макета и NSAnimationContext

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

(Извините, если GIF не зацикливается. Инструмент должен был создать зацикливание анимации, но, очевидно, не сделал...)

Когда он расширяется, внешний вид мгновенно меняет размер, а затем содержимое анимируется вверх обратно на место. Когда он сворачивается, снова размер меняется мгновенно, а затем содержимое прокручивается внутри него. Я хочу, чтобы изменение размера было анимированным, показывая / скрывая содержимое, не перемещая его относительно верхнего левого угла вмещающего вида.

Мой код выглядит так:

  NSAnimationContext.runAnimationGroup({
    context in
    context.duration = 0.25
    context.allowsImplicitAnimation = true
    // Order is important so we don't get conflicting constraints
    if newValue {
      closedConstraint.isActive = false
      openConstraint.isActive = true
    }
    else {
      openConstraint.isActive = false
      closedConstraint.isActive = true
    }
    layoutSubtreeIfNeeded()
  }, completionHandler: {
    self.disclosureButton.integerValue = newValue ? 1 : 0
  })

openConstraint ограничивает нижнюю часть окружающего вида нижней частью последнего поля. closedConstraint ограничивает его до нижней части текстовой метки вверху, поэтому видна только метка.

Итак, как мне а) анимировать границы вмещающего вида и б) держать содержимое привязанным к вершине во время анимации?

1 ответ

Я думаю, что ваша проблема проистекает из того факта, что при анимации ограничений макета анимация будет применяться только к изменению макета текущего представления.

Это означает, что, в то время как содержимое представления перераспределяется с анимацией, кадр не имеет анимации и, таким образом, перерисовывается немедленно.

Что вы можете сделать, чтобы обойти эту проблему, пытаясь оживить superview вместо. Я не уверен, как это будет работать внутри этого кода, но, возможно, попробуйте добавить superview?.setNeedsLayout() а также superview?.layoutIfNeeded() внутри вашего анимационного блока.

Я прошу прощения, если это не идеальное решение, поскольку я сталкивался с подобной проблемой в прошлом и также не нашел хорошего решения.

Дайте мне знать, если это поможет.

Другие вопросы по тегам