2012-12-15 3 views
5

Mam prostą animację, w której rozwijam nowy widok ze środka starego, podczas gdy ten zanika. Jednak podprzestrzenie tego nowego widoku (przycisk i etykieta) "leci" z dołu po prawej stronie ekranu, gdy nowy widok rozwija się, aby zająć cały ekran. Próbowałem z włączonym i wyłączonym autolayout, i chociaż te dwa scenariusze dają różne wyniki, oboje są w błędzie.Podstrony nie są prawidłowo pozycjonowane podczas animacji

Ustawiona jest prosta, mam dwie niepołączone kontrolerów widoku w serii ujęć, i użyć następującego kodu do animowania Zmień sposób wyświetlania:

-(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; 
     }]; 
} 

Pytanie jest, dlaczego nie zatrzymać się gdzie subviews oni mają wejść do ich superwizji, ponieważ animuje.

Odpowiedz

3

Aby wyhodować podrzędny w miejscu, szczególnie gdy używając Autolayout znacznie łatwiej jest animować właściwość transform zamiast ramki. W ten sposób właściwość obwiedni rzutu nie zmienia się, więc nie odczuwa potrzeby przekazywania jej podobieństw przez cały czas trwania animacji.

Dodaj swój wyskok z końcową klatką, ustaw jego transformację na skalowalną transformację afiniczną, powiedzmy, 0,1, a następnie animuj ją do transformacji tożsamości. Będzie rosnąć od punktu centralnego, z wszystkimi subviewsami we właściwej pozycji.

+0

Dzięki, nie mam dużego doświadczenia z transformacjami, więc staram się zapomnieć o tym sposobie robienia rzeczy. Chyba powinienem przeczytać. – rdelmar

1

Problem dotyczył ograniczeń układu. Jeśli zamiast ustawiania ramce widokowej w bloku animacji, dodaję wiązań pomiędzy oknem a nowy widok, a następnie zadzwonić layoutIfNeeded w bloku animacji działa poprawnie:

-(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; 
     }]; 
} 
+0

Pamiętaj, że jeśli używasz pełnego formularza, 'animateWithDuration: delay: options: animations: completion:', możesz przekazać 'UIViewAnimationOptionLayoutSubviews' i zrobi to' layoutIfNeeded' dla ciebie. –

+0

@robmayoff, właściwie to nie działało w tej sytuacji. Nie otrzymuję animacji, jeśli włączam tę opcję - przeskakuje ona do stanu końcowego. – rdelmar