Подвиды неправильно расположены во время анимации

У меня есть простая анимация, в которой я расширяю новый вид из центра старого, а тот исчезает. Однако подпредставления этого нового представления (кнопка и метка) «вылетают» из нижней правой части экрана, когда это новое представление расширяется и занимает весь экран. Я пробовал с включенным автомакетом и без него, и хотя два сценария дают разные результаты, оба они неверны.

Настройка проста, у меня есть два несвязанных контроллера представления в раскадровке, и я использую следующий код для анимации изменения представления:

-(void)switchViews2:(id)sender {
    UIWindow *win = self.view.window;
    YellowController *yellow = [self.storyboard instantiateViewControllerWithIdentifier:@"Yellow"];
    yellow.view.frame = CGRectMake(0, 0, 1, 1);
    yellow.view.center = self.view.center;
    [win addSubview:yellow.view];
    CGRect  frame = self.view.frame;
    [UIView animateWithDuration:5 animations:^{
        yellow.view.frame = frame;
        self.view.alpha = 0;
    }
             completion:^(BOOL finished) {
                 [self.view removeFromSuperview];
                 win.rootViewController = yellow;
         }];
}

Вопрос в том, почему подпредставления не остаются там, где они должны быть внутри своего суперпредставления, когда оно анимируется.


person rdelmar    schedule 15.12.2012    source источник


Ответы (2)


Чтобы увеличить подпредставление на месте, особенно при использовании Autolayout, гораздо проще анимировать свойство преобразования, а не фрейм. Таким образом, свойство границ подпредставления не изменяется, поэтому ему не нужно постоянно передавать свои подпредставления во время анимации.

Добавьте свое подпредставление с его последним кадром, установите его преобразование как масштабируемое аффинное преобразование, скажем, 0,1, затем анимируйте его до преобразования идентичности. Он будет расти из центральной точки со всеми подвидами в правильном положении.

person jrturton    schedule 15.12.2012
comment
Спасибо, у меня не так много опыта с преобразованиями, поэтому я обычно забываю об этом способе ведения дел. Думаю, мне следует дочитать. - person rdelmar; 15.12.2012

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

-(void)switchViews2:(id)sender {
    UIWindow *win = self.view.window;
    YellowController *yellow = [self.storyboard instantiateViewControllerWithIdentifier:@"Yellow"];
    [yellow.view setTranslatesAutoresizingMaskIntoConstraints:NO];
    yellow.view.frame = CGRectMake(0, 0, 1, 1);
    yellow.view.center = self.view.center;
    [win addSubview:yellow.view];

    NSLayoutConstraint *con1 = [NSLayoutConstraint constraintWithItem:yellow.view attribute:NSLayoutAttributeLeading relatedBy:0 toItem:win attribute:NSLayoutAttributeLeading multiplier:1 constant:0];
    NSLayoutConstraint *con2 = [NSLayoutConstraint constraintWithItem:yellow.view attribute:NSLayoutAttributeTop relatedBy:0 toItem:win attribute:NSLayoutAttributeTop multiplier:1 constant:20];
    NSLayoutConstraint *con3 = [NSLayoutConstraint constraintWithItem:yellow.view attribute:NSLayoutAttributeTrailing relatedBy:0 toItem:win attribute:NSLayoutAttributeTrailing multiplier:1 constant:0];
    NSLayoutConstraint *con4 = [NSLayoutConstraint constraintWithItem:yellow.view attribute:NSLayoutAttributeBottom relatedBy:0 toItem:win attribute:NSLayoutAttributeBottom multiplier:1 constant:0];

    [win addConstraints:@[con1,con2,con3,con4]];

    [UIView animateWithDuration:1 animations:^{
        [win layoutIfNeeded];
        self.view.alpha = 0;
    }
             completion:^(BOOL finished) {
                 [self.view removeFromSuperview];
                 win.rootViewController = yellow;
         }];
}
person rdelmar    schedule 15.12.2012
comment
Обратите внимание, что если вы используете полную форму, animateWithDuration:delay:options:animations:completion:, вы можете передать UIViewAnimationOptionLayoutSubviews, и она сделает layoutIfNeeded за вас. - person rob mayoff; 15.12.2012
comment
@robmayoff, на самом деле в этой ситуации это не сработало. Я не получаю анимацию, если включаю эту опцию — она переходит к конечному условию. - person rdelmar; 15.12.2012