2013-03-20 11 views
6

Einfaches Storyboard Setup: UIViewController mit UINavigationController. Bei einem Tabellenzellenklick drückt ein benutzerdefiniertes Segment einen neuen UIViewController auf den Navigationsstapel. Alles gut. Wenn Sie dann in der Navigationsleiste auf die Schaltfläche "Zurück" klicken, wird nur die Standard-Pop-Animation verwendet.Abwickeln mit benutzerdefiniertem Segment auf UINavigationController Pop über "Zurück" Knopf

Wie kann ich dem Navigationscontroller mitteilen, dass er mein benutzerdefiniertes Segment beim Zurückspringen verwenden soll? Ich habe hinzugefügt

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

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

zu beiden View-Controller, aber sie werden überhaupt nicht aufgerufen.

Was fehlt mir?

Antwort

11

Sie können dies erreichen, indem Sie einen benutzerdefinierten Übergang erstellen, anstatt einen benutzerdefinierten Übergang zu verwenden. Es hat eine Weile gedauert, bis ich es verstanden habe, aber es ist im Grunde sehr einfach. Stellen Sie nur sicher, dass Ihr erster View-Controller das UINavigationControllerDelegate-Protokoll annimmt. Dann noch in den ersten View-Controller, implementieren die folgende Methode:

- (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. 
} 

Noch in den ersten View-Controller, zum Beispiel in ViewDidLoad, erzählt der Navigation, dass der erste View-Controller als Delegierter fungiert:

self.navigationController.delegate = self; 

Erstellen Sie zuletzt eine Animator-Klasse, die das UIViewControllerAnimatedTransitioning-Protokoll annimmt. Implementieren die folgenden Methoden:

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

und

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

Das erste Verfahren enthält die Übergangscode. Dieser Übergangscode wird automatisch verwendet, wenn Sie auf die Schaltfläche Zurück tippen.

Hier ist eine sehr einfache example project.

+0

Ich habe versucht, Custom Animation mit Storyboard für Tage zu knacken! Vielen Dank ! Ihr Beispielprojekt hat sehr geholfen. UpVoted! :) – NavinDev

+0

Ich habe die navigationcontroller delegate-Methode zum navigationcontroller selbst hinzugefügt und seine Delegate auf sich selbst gesetzt und es funktioniert, so dass Sie diesen Prozess nicht tun müssen und dieses Protokoll in jedem vc im Stapel verwenden. – Arbitur

+0

@Arbitur Ich nehme an, dass dieser Navigationscontroller von Ihnen subclassed ist und über alle View-Controller im Stack vererbt wird, richtig? wenn nicht, wie machst du das, was du beschreibst? – Pavan

2

Haben Sie wie mit so etwas versucht:

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

Ich habe noch nie eine benutzerdefinierte segue gemacht, aber vorausgesetzt, sie wie alle anderen zusammenarbeiten tun, wenn sie, solange Ihre benutzerdefinierte segue Klasse überschreiben, um die UIStoryBoardSegue Subklassen sollte es funktionieren ...

Dann vergewissern Sie sich, dass Sie Ihre Zurück-Schaltfläche mit dem "Exit" -Symbol in der Leiste unter dem View-Controller verbunden haben.

+0

Wie oben erwähnt habe ich dies versucht und der Selector wird nicht aufgerufen. Es gibt auch keine Zurück-Taste, da diese vom Navigationscontroller kommt. – tcurdt

+1

Und das ist dein Problem ... Sie müssen eine benutzerdefinierte UIToolbar mit Ihrer eigenen UIButton "zurück" -Schaltfläche erstellen und mit dem Exit-Symbol verknüpfen und die unwind() -Methode über ein verbundenes touchUpInside-Ereignis aufrufen, das Sie für die Zurück-Schaltfläche erstellen . Das Problem ist, ist, dass Sie "nicht abwickeln()" können, wenn Sie die Rückseitenmethode eines Navigationscontrollers verwenden. Sie müssen die UINavigationsleiste ausblenden und Ihre eigene Lösung implementieren. – jpcguy89

+0

@tcurdt Sorry, von oben ist es eine UIToolbar mit einem UIBarButtonItem, kein UIButton – jpcguy89

2

Unwind-Segmente sind nützlich, um Segmente, einschließlich benutzerdefinierter Segmente, zurückzurollen. Das Problem in Ihrem Anwendungsfall liegt nicht in den Übergängen an sich, sondern darin, dass Sie den Abwicklungs-Übersprung von der Zurück-Schaltfläche auslösen möchten.

Das heißt, Sie könnten versuchen, dies zu umgehen, indem sie nicht Abwickeln verwenden, sondern eine benutzerdefinierte segue auslösen, wenn die Standard-Back-Taste abgegriffen wird:

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

dies Offensichtlich hat nichts mehr mit dem zu tun Abwickeln - es wird nur ein benutzerdefinierter Übergang ausgeführt, den Sie implementieren, um den Übergang, den Sie zum "Drücken" des Detailansicht-Controllers verwendet haben, "rückgängig" zu machen.

Lassen Sie mich wissen, wie das geht.

+0

Das Auslösen eines benutzerdefinierten Segments führt nicht zum Zurücksetzen eines Segments. Überprüfen Sie die kleinen Informationen, die da draußen sind. Sie müssen eine seltsame IBAction-Verbindung erstellen, damit ein Rollback funktioniert. – tcurdt

+0

Ja, Sie müssen (1) eine Methode mit dieser Signatur '- (IBAction) myUnwindMethod: (UIStoryboardSegue *) in Ihrem übergeordneten View-Controller implementieren, (2) ein Control im Child-View-Controller mit dem grünen Exit verbinden Symbol in (oder rufen Sie diese Methode manuell von -viewWillDisappear auf: in Ihrem Fall, weil Sie die Rücktaste des Navigationscontrollers "entführen" wollen) und (3) implementieren Sie die zwei Methoden, die Sie in Ihrer Frage erwähnen. –