Анимированное автоматическое создание макета с использованием UIKitDynamics

Я хотел бы использовать UIKitDynamics UISnapBehaviour, чтобы оживить анимацию (внешний вид + изменение положения при вращении) кнопки, которая сама позиционируется в виде с помощью Auto Layout.

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

  1. Получите целевой центр / границы кнопки до того, как произойдет переход на основе автоматического макета (но после его запуска). Сохраните это значение.
  2. Временно отключите все автоматическое расположение / ограничения кнопки
  3. Примените UISnapBehaviour. Подайте его с сохраненным целевым центром или значением границ из Auto Layout (из шага 1).
  4. Когда анимация 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, но приближается к нему довольно близко. Вы можете поэкспериментировать с синхронизацией и количеством поворотов в анимации ключевых кадров, а также с коэффициентом демпфирования пружины. Но это иллюстрирует один из подходов к получению похожего на поведение при использовании блочной анимации.

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