iOS: как анимировать к новому ограничению автопоставки (высота)

Я никогда раньше не работал с ограничениями автопоставки. У меня есть небольшое новое приложение, над которым я работаю, и заметило, что представления NIB по умолчанию имеют автоматическое расположение. Итак, я решил, что воспользуюсь возможностью поработать с ним и попытаюсь выяснить, куда Apple идет с этим.

Первый вызов:

Мне нужно изменить размер MKMapView, и я хотел бы анимировать его на новую позицию. Если я делаю это так, как я привык:

[UIView animateWithDuration:1.2f
     animations:^{
         CGRect theFrame = worldView.frame;
         CGRect newFrame = CGRectMake(theFrame.origin.x, theFrame.origin.y, theFrame.size.width, theFrame.size.height - 170);
         worldView.frame = newFrame;
}];

... тогда MKMapView будет "привязываться" к своей первоначальной высоте всякий раз, когда обновляется родственное представление (в моем случае обновляется заголовок UISegmentedControl [myUISegmentedControl setTitle:newTitle forSegmentAtIndex:0]).

Итак, я думаю, что я хочу сделать, это изменить ограничения MKMapView с того, чтобы они были равны высоте родительского представления, чтобы быть относительно вершины UISegmentedControl, который он покрывал: V:[MKMapView]-(16)-[UISegmentedControl]

Я хочу, чтобы высота MKMapView была укорочена, чтобы раскрылись некоторые элементы управления под видом карты. Для этого я думаю, что мне нужно изменить ограничение с фиксированного полноразмерного представления на такое, где нижний предел ограничен вершиной UISegmentedControl... и я бы хотел, чтобы он анимировался при уменьшении представления до нового размера.

Как можно это сделать?

Редактировать - эта анимация не анимируется, хотя нижняя часть вида мгновенно перемещается вверх на 170:

    [UIView animateWithDuration:1.2f
         animations:^{
             self.nibMapViewConstraint.constant = -170;

    }];

и nibMapViewConstraint подключен в IB к нижнему ограничению вертикального пространства.

6 ответов

После обновления вашего ограничения:

[UIView animateWithDuration:0.5 animations:^{[self.view layoutIfNeeded];}];

замещать self.view со ссылкой на содержащий вид.

Это работает для меня (как iOS7 и iOS8+). Нажмите на ограничение автоматического размещения, которое вы хотите настроить (в конструкторе интерфейса, например, ограничение сверху). Затем сделайте это IBOutlet;

@property (strong, nonatomic) IBOutlet NSLayoutConstraint *topConstraint;

Оживить вверх;

    self.topConstraint.constant = -100;    
    [self.viewToAnimate setNeedsUpdateConstraints]; 
    [UIView animateWithDuration:1.5 animations:^{
        [self.viewToAnimate layoutIfNeeded]; 
    }];

Оживить обратно в исходное место

    self.topConstraint.constant = 0;    
    [self.viewToAnimate setNeedsUpdateConstraints];  
    [UIView animateWithDuration:1.5 animations:^{
        [self.viewToAnimate layoutIfNeeded];
    }];

Существует очень хороший учебник от самого Apple, который объясняет, как использовать анимацию с автопоставкой. Перейдите по этой ссылке, а затем найдите видео под названием "Автоматическая разметка по примеру". В нем содержатся некоторые интересные сведения об автопоставке, а в последней части рассказывается о том, как использовать анимацию.

Я сделал эту небольшую демоверсию доступной. Это показывает, как ограничения автоматического макета могут быть изменены и анимированы в очень простом примере. Просто взгляните на DemoViewController.m.

Большинство людей используют autolayout для размещения элементов на своих представлениях и изменения ограничений макета для создания анимации.

Простой способ сделать это без большого количества кода - создать UIView, который вы хотите анимировать в раскадровке, а затем создать скрытый UIView, где вы хотите, чтобы UIView заканчивался. Вы можете использовать предварительный просмотр в xcode, чтобы убедиться, что оба UIViews находятся там, где вы хотите, чтобы они были. После этого скройте конечный UIView и поменяйте местами ограничения макета.

Существует подфайл для замены ограничений макета, который называется SBP, если вы не хотите писать его самостоятельно.

Вот учебник.

Нет необходимости использовать больше IBOutlet reference ограничения вместо этого вы можете напрямую access или же update уже примененное ограничение либо применяется Programmatically или из Interface Builder в любом представлении, используя KVConstraintExtensionsMaster библиотека. Эта библиотека также управляет Cumulative поведение NSLayoutConstraint,

Чтобы добавить ограничение высоты на containerView

 CGFloat height = 200;
 [self.containerView applyHeightConstrain:height];

Чтобы обновить ограничение высоты контейнера с анимацией

[self.containerView accessAppliedConstraintByAttribute:NSLayoutAttributeHeight completion:^(NSLayoutConstraint *expectedConstraint){
        if (expectedConstraint) {
            expectedConstraint.constant = 100;

            /* for the animation */ 
            [self.containerView  updateModifyConstraintsWithAnimation:NULL];
      }
    }];
Другие вопросы по тегам