2013-09-21 10 views
16

Mein Ziel ist es, Zoomen modalen Übergang für den Benutzer aus einer ähnlichen Ansicht wie springen Sprungbrettzeichen beim Starten von Apps.Navigationsleiste wird nach Aufruf von completeTransition angepasst: in benutzerdefinierten Übergang

Der vorgestellte View-Controller zoomt korrekt, aber die Navigationsleiste hat eine falsche Position unter der Statusleiste. Diese Position wird nach dem Aufruf von [transitionContext completeTransition: finished] korrigiert. Wie kann ich es von Anfang an richtig machen?

Dies ist eine Bildschirmaufnahme des Fehlers: http://youtu.be/7LKU4lzb-uw (der Fehler im sechsten Sekunde der Aufnahme ist)

Der UIViewControllerAnimatedTransitioning Code:

- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext 
{ 
    UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]; 
    UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; 
    UIView *container = [transitionContext containerView]; 

    CGPoint viewCenter = self.view.center; 
    CGSize viewSize = self.view.frame.size; 
    CGSize controllerSize = toViewController.view.frame.size; 

    CGFloat controllerFromX = viewCenter.x - (controllerSize.width/2); 
    CGFloat controllerFromY = viewCenter.y - (controllerSize.height/2); 

    CGAffineTransform transform = CGAffineTransformMakeTranslation(controllerFromX, controllerFromY); 
    transform = CGAffineTransformScale(transform, viewSize.width/controllerSize.width, viewSize.height/controllerSize.height); 

    if (self.reverse) { 
     [container insertSubview:toViewController.view belowSubview:fromViewController.view]; 
    } else { 
     toViewController.view.transform = transform; 
     [container addSubview:toViewController.view]; 
    } 

    [UIView animateKeyframesWithDuration:ZoomTransitioningDuration 
            delay:0 
           options:0 
           animations:^{ 
       if (self.reverse) { 
        fromViewController.view.alpha = 0.0f; 
        fromViewController.view.transform = transform; 
       } else { 
        toViewController.view.transform = CGAffineTransformIdentity; 
       } 
     } 
           completion:^(BOOL finished) { 
       [transitionContext completeTransition:finished]; 
     }]; 
} 
+0

Können Sie den y-Ursprung der entsprechenden Ansicht nicht anpassen? –

+0

Wenn ich das tue, ist der Bereich unterhalb der Statusleiste schwarz, nicht grün (der gesamte Controller wird nach unten verschoben). –

+0

Woher kommt self.view? Ist der präsentierende View-Controller auch der Animations-Controller? – bilobatum

Antwort

25

Das Problem ist, dass Sie die Transformation vor setzen das Ziel View-Controller-Sicht in die Behälter eingeführt wird.

den Auftrag Schalt sollte es beheben:

if (self.reverse) { 
    [container insertSubview:toViewController.view belowSubview:fromViewController.view]; 
} else { 
    [container addSubview:toViewController.view]; 
    toViewController.view.transform = transform; 
} 

Siehe auch Punkt 4 here. Da Sie vor dem Einfügen der Ansicht des Navigationssteuerelements als Teilansicht eine Transformation angewendet haben, ist die Layout-Steuerkomponente nicht der Ansicht, dass sich die Navigationsleiste am oberen Rand des Fensters befindet und daher nicht angepasst werden muss, um den Status zu vermeiden Bar.

+0

Es hat für mich funktioniert! Vielen Dank! – Bivis

+0

Arbeitete auch für mich! Vielen Dank! – Georg

+0

Habe einen halben Tag damit verbracht, eine Lösung zu finden - funktioniert perfekt! – Vytis

6

ich eine Lösung gefunden haben, obwohl ziemlich hacky. Ich muß manuell die Navigationsleiste Rahmen anpassen, bevor die Animation beginnt:

if (self.reverse) { 
    [container insertSubview:toViewController.view belowSubview:fromViewController.view]; 
} else { 
    toViewController.view.transform = transform; 
    [container addSubview:toViewController.view]; 

    // fix navigation bar position to prevent jump when completeTransition: is called 
    if ([toViewController isKindOfClass:[UINavigationController class]]) { 
     UINavigationController* navigationController = (UINavigationController*) toViewController; 
     UINavigationBar* bar = navigationController.navigationBar; 
     CGRect frame = bar.frame; 
     bar.frame = CGRectMake(frame.origin.x, frame.origin.y + 20.0f, frame.size.width, frame.size.height); 
    } 
} 
+2

Das Problem dabei ist, dass es das Problem nur beim ersten Mal behebt. Wird derselbe View-Controller später erneut angezeigt, wird die Navigationsleiste ebenfalls um 20 Pixel kleiner. – roperklacks

+0

es funktioniert gut, aber nicht für farbige Navigationsleiste. – yershuachu

+1

bar.frame = CGRectMake (frame.origin.x, frame.origin.y, frame.size.width, frame.size.height + 20.0f); ist viel besser;) – yershuachu

0

Dies ist immer noch ein Hack, basierend auf Ondřej Mirtes' ein, aber es funktioniert besser, wenn Sie eine in-Call-Statusleiste haben und Sie sind auf iOS8

if([toViewController isKindOfClass:[UINavigationController class]]) { 
    UINavigationController *navCtrl = (UINavigationController *)toViewController; 
    UINavigationBar *navBar = navCtrl.navigationBar; 
    if(navBar.frame.origin.y == 0 && navBar.frame.size.height == 44) { 
    navBar.frame = CGRectMake(0, 0, navBar.frame.size.width, fmin(44 + [UIApplication sharedApplication].statusBarFrame.size.height, 64)); 
    } 
} 

bleibt hässlich aber:/

1

Fügen Sie toViewControllerView zuerst in die ContainerView ein und legen Sie dann die toViewControllerView-Transformation wie unten angegeben fest.

[Container addSubview: toViewController.view];

toViewController.view.transform = transformieren;

Dies wird das Problem lösen.

Verwandte Themen