Различия в различиях анимации ограничений AutoLayout в iOS 10?
Я заметил, что в iOS 10 Beta 5 (собирается попробовать Beta 6) анимация ограничений AutoLayout ведет себя по-другому.
Например, этот подход не работает так же, как в предыдущих версиях iOS:
[view addConstraints:@[constraints...]];
[view setNeedsUpdateConstraints];
[view layoutIfNeeded];
[UIView animateWithDuration:...
{
/* adjust constraint here... */
[view layoutIfNeeded]; // Only the adjusted constraints since previous layoutIfNeeded() call should animate change with duration.
} completion:{ ... }];
... В моем тестировании ограничения, первоначально добавленные с помощью addConstraints()
, будут также анимировать в iOS 10 с блоком UIView animateWithDuration()
..., что вызывает некоторое вредное/нежелательное поведение, поэтому далеко.
Например, установка ограничений влево/вправо в массиве (но вертикальные ограничения в блоке) заставляет весь вид анимировать на экране по диагонали с помощью этого подхода... который полностью неверно.
Кто-нибудь знает, как сделать это правильно как для iOS 9 (и ниже), так и для 10?
Ответы
Ответ 1
Попробуйте вызвать layoutIfNeeded
в представлении view, а не в самом представлении.
-
У меня была аналогичная проблема, мой взгляд должен был анимироваться сверху с высоты 0, вниз до высоты > 0 (т.е. (0, 0, 320, 0) до (0, 0, 320, 44)).
Используя Xcode 8 с iOS 10, поведение анимации было сильно иным. Вместо того, чтобы анимировать вниз сверху, представление анимируется вверх и вниз от вертикального центра кадра назначения.
Я исправил это, вместо того, чтобы называть layoutIfNeeded
на самом представлении, вызывая его в представлении viewview. Каким-то образом поведение было восстановлено.
Надеюсь, что это поможет!
Полезный комментарий от @Ramiro:
В соответствии с документацией layoutIfNeeded
излагает subviews (но не рассматривает текущее представление). Итак, чтобы обновить текущее представление, вы должны вызвать layoutIfNeeded
из супер-представления.
Ответ 2
В приведенном ниже методе:
[super viewDidLoad];
Запишите эту строку:
[self.view layoutIfNeeded];
Ответ 3
Я сделал небольшой тест, изменяя H и V небольшого красного вида:
self.red_POS_H = NSLayoutConstraint.constraints(withVisualFormat: "H:|-90-[redView]", options: defaultOptions, metrics: nil, views: viewsDictionary)
self.red_POS_V = NSLayoutConstraint.constraints(withVisualFormat: "V:|-30-[redView]", options: defaultOptions, metrics: nil, views: viewsDictionary)
self.view.addConstraints(self.red_POS_V!)
self.view.addConstraints(self.red_POS_H!)
и оживить его:
// we hope is only one:
let currV = self.red_POS_V![0]
let currH = self.red_POS_H![0]
UIView.animate(withDuration: 3) {
// Make all constraint changes here
currV.constant = 100
currH.constant = 300
self.view.layoutIfNeeded() // Forces the layout of the subtree animation block and then captures all of the frame changes
}
красный вид перемещен правильно, если вы прокомментируете одиночную строку в анимации, она работает, по горизонтали или по вертикали.
Малый проект доступен, если вам это нужно.