Анимированное автоматическое создание макета с использованием UIKitDynamics
Я хотел бы использовать UIKitDynamics UISnapBehaviour, чтобы оживить анимацию (внешний вид + изменение положения при вращении) кнопки, которая сама позиционируется в виде с помощью Auto Layout.
Я понимаю, что при применении сил UIKitDynamics мне нужно временно отключить ограничения авторазметки для кнопки. Я думаю о следующем процессе...
- Получите целевой центр / границы кнопки до того, как произойдет переход на основе автоматического макета (но после его запуска). Сохраните это значение.
- Временно отключите все автоматическое расположение / ограничения кнопки
- Примените UISnapBehaviour. Подайте его с сохраненным целевым центром или значением границ из Auto Layout (из шага 1).
- Когда анимация UIKitDynamics закончена, повторно включите ограничения, чтобы подготовиться к любому дальнейшему изменению макета
Это правильный подход?
Какой делегат / макет следует использовать для этих соответствующих шагов + как получить целевой центр вида из Auto Layout до того, как произойдет фактическая анимация / переход на основе Auto Layout?
1 ответ
Я мог бы предложить другой подход, который приближает UISnapBehavior
, но избегает попытки объединить UIKit Dynamics с автоматическим макетом, в котором вы полагаетесь на механизм автоматического макета для определения конечной позиции представления. (Очевидно, что если вы знали конечный пункт назначения, вы просто приостановили бы автоматическое размещение, привязку, а когда привязка была сделана, вы бы применили ограничения.)
Для эффекта отскакивания, когда вид защелкивается, вы можете использовать animateWithDuration
с usingSpringWithDamping
параметр, например:
// create the view
UIView *view = ...;
view.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:view];
// add all of the constraints for the final position
NSDictionary *views = NSDictionaryOfVariableBindings(view);
[self.view addConstraints:...];
// animate the application of those constraints with low `withSpringWithDamping`
[UIView animateWithDuration:1.0 delay:0.0 usingSpringWithDamping:0.5 initialSpringVelocity:0.0 options:0 animations:^{
[view layoutIfNeeded];
} completion:nil];
Если вы также хотите немного поворота, чтобы он встал на место, вы можете использовать animateKeyframesWithDuration
:
[UIView animateKeyframesWithDuration:1.0 delay:0.0 options:0 animations:^{
[UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.5 animations:^{
view.transform = CGAffineTransformMakeRotation(M_PI_4 / 2);
}];
[UIView addKeyframeWithRelativeStartTime:0.5 relativeDuration:0.25 animations:^{
view.transform = CGAffineTransformMakeRotation(-M_PI_4 / 4);
}];
[UIView addKeyframeWithRelativeStartTime:0.75 relativeDuration:0.125 animations:^{
view.transform = CGAffineTransformMakeRotation(M_PI_4 / 16);
}];
[UIView addKeyframeWithRelativeStartTime:0.875 relativeDuration:0.125 animations:^{
view.transform = CGAffineTransformMakeRotation(0);
}];
} completion:nil];
Это не совсем UISnapBehavior
, но приближается к нему довольно близко. Вы можете поэкспериментировать с синхронизацией и количеством поворотов в анимации ключевых кадров, а также с коэффициентом демпфирования пружины. Но это иллюстрирует один из подходов к получению похожего на поведение при использовании блочной анимации.