2014-04-05 8 views
6

Come è possibile ottenere transizioni personalizzate (iOS7) quando si spinge un controller di visualizzazione su UINavigationController? Ho provato a impostare lo TransitioningDelegate sia nello UINavigationController sia sul controller che sto premendo I metodi non vengono mai chiamati.Come utilizzare UIViewControllerAnimatedTransitioning con UINavigationController?

Tutti gli esempi che trovo usano transizioni personalizzate quando si presentano modalmente.

+0

Si prega di contrassegnare una risposta come corretta in risposta alla tua domanda – rounak

risposta

18

@rounak ha l'idea giusta, ma a volte aiuta ad avere il codice pronto senza dover scaricare da github.

qui sono i passi che ho preso:

  1. Fai la tua FromViewController.m conforme alle UINavigationControllerDelegate. Altri esempi di codice là fuori ti dicono di conformarti allo UIViewControllerTransitioningDelegate, ma solo se sei presentando il ToViewController.

    @interface ViewController: UIViewController

  2. Ritorna l'oggetto transizione animatore personalizzato nel metodo di callback delegato in FromViewController:

    - (id <UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController 
               animationControllerForOperation:(UINavigationControllerOperation)operation 
                  fromViewController:(UIViewController *)fromVC 
                   toViewController:(UIViewController *)toVC { 
        TransitionAnimator *animator = [TransitionAnimator new]; 
        animator.presenting = (operation == UINavigationControllerOperationPush); 
        return animator; 
    } 
    
  3. Creare la classe animatore personalizzato e incollare questi metodi di campionamento:

    - (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext { 
        return 0.5f; 
        } 
    
    - (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext  { 
    // Grab the from and to view controllers from the context 
    UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]; 
    UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; 
    
    // Set our ending frame. We'll modify this later if we have to 
    CGRect endFrame = CGRectMake(80, 280, 160, 100); 
    
    if (self.presenting) { 
        fromViewController.view.userInteractionEnabled = NO; 
    
        [transitionContext.containerView addSubview:fromViewController.view]; 
        [transitionContext.containerView addSubview:toViewController.view]; 
    
        CGRect startFrame = endFrame; 
        startFrame.origin.x += 320; 
    
        toViewController.view.frame = startFrame; 
    
        [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{ 
         fromViewController.view.tintAdjustmentMode = UIViewTintAdjustmentModeDimmed; 
         toViewController.view.frame = endFrame; 
        } completion:^(BOOL finished) { 
         [transitionContext completeTransition:YES]; 
        }]; 
    } 
    else { 
        toViewController.view.userInteractionEnabled = YES; 
    
        [transitionContext.containerView addSubview:toViewController.view]; 
        [transitionContext.containerView addSubview:fromViewController.view]; 
    
        endFrame.origin.x += 320; 
    
        [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{ 
         toViewController.view.tintAdjustmentMode = UIViewTintAdjustmentModeAutomatic; 
         fromViewController.view.frame = endFrame; 
        } completion:^(BOOL finished) { 
         [transitionContext completeTransition:YES]; 
        }]; 
    } 
    } 
    

In sostanza, l'animatore è l'oggetto che fa il sollevamento pesante. Naturalmente, puoi rendere UINavigationControllerDelegate un oggetto separato, ma dipende da come il tuo architetto app.

+0

funziona per iOS 8? – SleepsOnNewspapers

+0

sì, dovrebbe funzionare – josephmisiti

1

EDIT: Ho appena realizzato che questo potrebbe non rispondere alla tua domanda. Ma è un'alternativa.

Se si utilizza uno storyboard, è possibile eseguire una transizione personalizzata creando un seguito personalizzato. Nella finestra di ispezione attributi, modificare il nome della classe seguito nella classe di transizione personalizzata, ad es. MySegue. Quindi creare la classe MySegue e implementare il metodo -(void)perform per eseguire la transizione. alberino

- (void) perform{ 
     UIViewController *source = self.sourceViewController; 
     UIViewController *destination = self.destinationViewController; 
     [UIView transitionFromView:source.view 
          toView:destination.view 
         duration:0.50f 
         options:UIViewAnimationOptionTransitionFlipFromTop 
         completion:nil]; 
} 
4

di objc.io su transizioni vista controllore sono specificamente per la spinta e iniziano vista controllori. http://objc.io/issue-5/view-controller-transitions.html

Ho realizzato questa animazione (http://i.imgur.com/1qEyMu3.gif) basata esclusivamente sul post objc.io.

In breve, è necessario avere una o più classi che implementino UINavigationControllerDelegate e UIViewControllerAnimatedTransitioning con i metodi richiesti per restituire l'animatore corretto ed eseguire le animazioni.

+0

Puoi condividere il codice animatore, sto lavorando su cose simili come mostrato nell'immagine. –

+0

Ho dato CGAffineTransform (translationX: 1.02, y: 1.02) durante push e durante pop (0.01,0.01) sembra funzionare bene, vorrei sapere qual è il tuo valore anche :) –