2013-03-20 4 views
6

Impostazione storyboard semplice: UIViewController con UINavigationController. Su una cella della tabella, fare clic su una sequenza personalizzata spinge un nuovo UIViewController nello stack di navigazione. Tutto bene. Ma premendo il pulsante "indietro" nella barra di navigazione, utilizza solo l'animazione pop predefinita.svolgersi con le sequenze personalizzate su UINavigationController pop tramite il pulsante "Indietro"

Come faccio a dire al controller di navigazione di utilizzare i miei passaggi personalizzati quando compaiono? Ho aggiunto

- (UIStoryboardSegue *)segueForUnwindingToViewController:(UIViewController *)toViewController fromViewController:(UIViewController *)fromViewController identifier:(NSString *)identifier 

- (BOOL)canPerformUnwindSegueAction:(SEL)action fromViewController:(UIViewController *)fromViewController withSender:(id)sender 

ad entrambi i controller di vista, ma non ottengono chiamato a tutti.

Cosa mi manca?

risposta

11

È possibile eseguire questa operazione creando una transizione personalizzata anziché utilizzare un seguito personalizzato. Mi ci è voluto un po 'per capire, ma è fondamentalmente molto semplice. Assicurati che il tuo primo controller di visualizzazione adotti il ​​protocollo UINavigationControllerDelegate. Poi, ancora nel primo controller di vista, implementare il seguente metodo:

- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController 
           animationControllerForOperation:(UINavigationControllerOperation)operation 
              fromViewController:(UIViewController *)fromVC 
              toViewController:(UIViewController *)toVC 
{ 
return X // where X is an animation Controller object, an instance of the animator class. 
} 

Sempre nel primo controller di vista, ad esempio in viewDidLoad, dire al navigationController che il primo controllore vista agirà come suo delegato:

self.navigationController.delegate = self; 

Ultimo ma non meno importante, creare una classe animatore che adotta il protocollo UIViewControllerAnimatedTransitioning. Implementare i seguenti metodi:

- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext 

e

- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext 

Il primo metodo contiene il codice transizione. Questo codice di transizione verrà utilizzato automaticamente quando toccato sul pulsante Indietro.

Ecco un semplicissimo example project.

+0

Stavo cercando di decifrare l'animazione personalizzata usando lo storyboard per giorni! Grazie ! il tuo progetto di esempio ha aiutato molto. UpVoted! :) – NavinDev

+0

Ho aggiunto il metodo delegato navigationcontroller al controller di navigazione stesso e impostato il suo delegato su se stesso e funziona, quindi non devi fare quel processo e utilizzare quel protocollo in ogni vc nello stack. – Arbitur

+0

@Arbitur Presumo che questo tuo controller di navigazione sia sottoclasse ed è ereditato da tutti i controller di vista nello stack, giusto? se no, come stai facendo ciò che descrivi? – Pavan

2

Hai provato a usare qualcosa di simile a:

- (UIStoryboardSegue *)segueForUnwindingToViewController:(UIViewController *)toViewController fromViewController:(UIViewController *)fromViewController identifier:(NSString *)identifier 
{ 
    return [MyCustomSegueInitMethod viewControllerA:vc1 viewControllerB: vcB]; 
} 

Non ho mai fatto un segue personalizzato, ma ammesso che funzionano come tutti gli altri fare quando li ignorando, a patto che la classe segue personalizzata viene sottoclasse della UIStoryBoardSegue , dovrebbe funzionare ...

Quindi assicurati di aver collegato il pulsante Indietro all'icona "esci" nella barra sotto il controller della vista.

+0

Come detto sopra ho provato questo e il selettore non viene chiamato. Inoltre, non esiste un pulsante indietro, come quello che viene dal controller di navigazione. – tcurdt

+1

E questo è il tuo problema ... È necessario creare una UIToolbar personalizzata con il proprio pulsante "indietro" UIButton e collegarlo all'icona di uscita e chiamare il metodo unwind() tramite un evento touchUpInside connesso che si crea per il pulsante Indietro . Il problema è che non è possibile "unwind()" se si utilizza il metodo back di un controller di navigazione. Devi nascondere la barra di UINavigation e implementare la tua soluzione. – jpcguy89

+0

@tcurdt Mi spiace, da sopra, è una UIToolbar con un UIBarButtonItem, non un UIButton – jpcguy89

2

I segui di Svolgimento sono utili per "rollback" segues, inclusi i segui personalizzati. Il problema nel tuo usecase non sta nei segues di per sé, ma nel fatto che vuoi attivare i seguiti del unwind dal pulsante back.

Detto questo, si potrebbe tentare di ovviare a questo, non utilizzando svolgimento, ma innescare un segue personalizzato quando il-back-pulsante standard è sfruttato:

// MyDetailViewController.m: 
- (void)viewWillDisappear:(BOOL)animated 
{ 
    if ([self.navigationController.viewControllers indexOfObject:self] == NSNotFound) { 
     // trigger custom segue (but note that the sourceViewController 
     // has already been removed from the nav controller) 
    } 
    [super viewWillDisappear:animated]; 
} 

Ovviamente questo non ha più nulla a che fare con svolgimento - sta semplicemente eseguendo una sequenza personalizzata che implementa per "ripristinare" i passaggi che hai usato per "spingere" il controller della vista di dettaglio in primo luogo.

Fammi sapere come va.

+0

L'attivazione di un seguito personalizzato non ripristina un seguito. Controlla le piccole informazioni che sono là fuori. Devi creare una strana connessione IBAction per far funzionare un rollback. – tcurdt

+0

Sì, sarà necessario (1) implementare un metodo con questa firma '- (IBAction) myUnwindMethod: (UIStoryboardSegue *) segue' nel controllore della vista genitore, (2) connettere alcuni controlli nel controller della vista figlio all'uscita verde icona in (o chiama manualmente questo metodo da -viewWillDisappear: nel tuo caso, perché vuoi "dirottare" il pulsante indietro del controller di navigazione), e (3) implementare i due metodi che menzioni nella tua domanda. –