В любое время по моему приложению я замечаю, что когда я звоню UIView.animateWithDuration
, если у меня есть какие-либо другие запросы автоматической компоновки или даже что-то такое же простое, как изменение константа NSLayoutConstraint
, эти изменения также будут анимированы, даже если они НЕ находятся внутри блока анимации. Например: у меня есть UIViewController
, который сразу после вызова viewDidAppear
добавит изображение, которое было выбрано пользователем, на UIScrollView
, чтобы его можно было изменить и отредактировать. Я работаю над добавлением небольшого демонстрационного представления с некоторыми GIF, чтобы помочь пользователю при первом использовании этого приложения. Как только появится представление, он должен добавить изображение (я установил его, чтобы оно соответствовало их экрану вначале), в scrollView, а затем анимировать demonstrationView
альфа от нуля до 1.0. Проблема, которую я испытываю, хотя моя функция добавления и изменения размера изображения assignImageChosen
вызывается до animateWithDuration
и находится вне блока анимации, изменения в ограничениях размера также анимируются.UIView animateWithDuration Анимация Auto-Layout Views За пределами блока анимации
override func viewDidAppear(animated: Bool) {
if let image = startImage {
self.assignImageChosen(image)
currentlyEditing = true
}
if preLoadGame {
UIView.animateWithDuration(1.0, delay: 0.5, options: UIViewAnimationOptions.CurveEaseInOut, animations: {
self.demonstrationView.alpha = 1.0
self.view.layoutIfNeeded()
}, completion: nil)
}
}
Вот функция assignImageChosen
:
func assignImageChosen(image: UIImage) {
var ratio:CGFloat!
let screen:CGFloat = max(self.scrollView.frame.height, self.scrollView.frame.width)
var maxImage:CGFloat!
if UIDevice.currentDevice().orientation.isPortrait {
if image.size.height >= image.size.width {
maxImage = max(image.size.height, image.size.width)
}
else {
maxImage = min(image.size.height, image.size.width)
}
}
else {
if image.size.width >= image.size.height {
maxImage = max(image.size.height, image.size.width)
}
else {
maxImage = min(image.size.height, image.size.width)
}
}
if maxImage > screen {
ratio = screen/maxImage
}
else {
ratio = 1.0
}
self.imageView.image = image
self.imageHeight.constant = image.size.height * ratio
self.scrollView.contentSize.height = image.size.height * ratio
self.imageWidth.constant = image.size.width * ratio
self.scrollView.contentSize.width = image.size.width * ratio
}
Переменные imageHeight
и imageWidth
оба NSLayoutConstraint
«s, и imageView
является UIImageView
, к которому они установлены. Поэтому, как только я изменяю изображение, я меняю ограничения, чтобы изображениеView внутри UIScrollView
соответствовало экрану. Проблема в том, что когда я делаю это так, хотя изменения вызывают вне блока анимации, эти изменения все еще анимируются.
Вот пример GIF того, что я пытаюсь (плохо), чтобы общаться с помощью слов:
Я нашел способ обойти эту проблему, но он чувствует себя, как полный хака. Я вручную закодировать систему, чтобы задержать выполнение анимации с помощью команды dispatch_after
следующим образом:
override func viewDidAppear(animated: Bool) {
if let image = startImage {
self.assignImageChosen(image)
currentlyEditing = true
}
if preLoadGame {
let delay = 0.5 * Double(NSEC_PER_SEC)
let popTime = dispatch_time(DISPATCH_TIME_NOW, Int64(delay))
dispatch_after(popTime, dispatch_get_main_queue(), {
UIView.animateWithDuration(1.0, delay: 0, options: UIViewAnimationOptions.CurveEaseInOut, animations: {
self.demonstrationView.alpha = 1.0
self.view.layoutIfNeeded()
}, completion: nil)
})
}
}
Таким образом, вместо того, чтобы использовать переменную delay
внутри функции animateWithDuration
, я вместо того, чтобы задержать выполнение функции. Это работает, но я думаю, что должен быть лучший способ сделать это! Почему эти изменения макета анимируются, когда они не находятся внутри блока анимации? Как я могу обойти это правильно, эффективно?
Вот как это выглядит с моей хак, и как я предположил бы, что он должен выглядеть без него:
Я признателен за любую помощь с этим вопросом расстраивает!
Wow thank you! Я не могу поверить, насколько невероятно просто было решение. Эта проблема периодически меня била месяцами! Это всегда горько-сладкий, когда ответ такой простой: приятно знать, что его так легко исправить, что вам сложно разобраться в том, что вы так потратили столько времени на что-то такое простое! еще раз спасибо – Pierce