6

ich ein paar Antworten auf dieser Seite versucht, aber keiner von ihnen scheinen zu meinem Problem zu beziehenDismissing beid UINavigation Ansichten und Modal Ansichten auf einmal programmatisch

Ich habe einen Masterdetail-App, die eine zwei Arten von segues hat, dass Ich benutze. Wenn Sie auf eine Schaltfläche in der Detailansicht drücken, wird ein Push-Segment verwendet und eine weitere Detailansicht darauf verschoben. In der neuen Detailansicht (der gerade gedrückten) befindet sich eine Schaltfläche, die mit einem modalen Übergang ein weiteres UIView (Formularblatt) aufruft.

Was ich versuche zu tun ist, wenn der Benutzer eine Zeile auswählt, wird eine UIAlertView zeigt eine Meldung angezeigt, während zur gleichen Zeit (nicht am gleichen Zeit sein muß), es entlässt die Uiviewcontroller (modal) und geht zurück von dem Viewcontroller, der angeschaltet wurde. Grundsätzlich muss ich in der Lage sein, alle Viewcontroller, einen modalen und einen Push (nav) zu verwerfen, so dass die Ansicht zu dem ursprünglichen Hauptbildschirm zurückkehrt, mit dem sie gestartet wurden.

Ich habe die UIAlertView funktioniert gut und ich kann den modalen Viewcontroller zu entlassen, indem Sie [self.dismissViewControllerAnimated:YES completion:nil]; verwenden, aber ich weiß nicht, wie der nächste Viewcontroller (der in einem Navigationscontroller ist) zu entlassen. Verwenden Sie dies: [self.navigationController popToRootViewControllerAnimated:NO]; funktioniert nicht.

Hier ist, wo ich will die Funktion aufgerufen werden alle Ansichten zu entfernen:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 

    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlWithIDAndChallenge]; 

    NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self]; 

    UIAlertView *message = [[UIAlertView alloc] [email protected]"Started" message:@"The challenge has begun!" delegate:nil cancelButtonTitle:@"OK!" otherButtonTitles:nil]; 

    [message show] 

    //right here is where I would normally dismiss the modal VC 
    //here is where I would like to dismiss all VC 

} 
+0

Was iOS-Versionen unterstützen Sie? Wenn Sie nur iOS 6 verwenden, können Sie Abwicklungssegmente verwenden, die dies sehr elegant machen. – Rob

+0

@Rob Ich benutze iOS6 – CaptJak

+0

Dieses Gefühl, wenn ich Antwort auf meine Frage in Ihrer Frage gefunden habe. Danke vielmals. –

Antwort

14

Wenn Sie möchten, können Sie in Projekten mit iOS 6.0 (und höher) ein Abwicklungssegment verwenden.Zum Beispiel können Sie:

  1. In Ihren Top-Level-View-Controller (die, die Sie -, nicht die Steuerung Sie gehen entspannen von entspannen wollen), schreiben Sie eine Abwickelstation segue Methode, in diesem Fall unwindToTopLevel genannt (persönlich, finde ich es sinnvoll, wenn die segue einige Hinweise darüber, was das Ziel der segue ist trägt, aus Gründen, die offensichtlich werden, wenn wir Schritt 3 erhalten, unten):

    - (IBAction)unwindToTopLevel:(UIStoryboardSegue *)segue 
    { 
        NSLog(@"%s", __FUNCTION__); 
    } 
    
  2. In der Interface Builder-Szene von whi ch initiieren Sie den Abwickler, Steuer ⌘ -Ziehen aus dem View-Controller-Symbol auf das Symbol Verlassen der Abwickler segue zu erstellen:

    enter image description here

    Im Allgemeinen würden Sie die segue von einer Schaltfläche zum Ausgang definieren outlet (und fertig), aber wenn Sie das Segment programmgesteuert aufrufen möchten, möchten Sie es möglicherweise zwischen dem Controller und der Abwicklungsdose erstellen, wie oben gezeigt.

  3. Du wirst ein wenig Pop-up erhalten, die den Namen Ihres Abroller segues enthält (von den präsentierenden Controller ... es wie Magie):

    enter image description here

  4. Wenn Sie geht aufrufen, die segue programmatisch, können Sie diese Abroller segue in dem Dokument Umriss auf der linken Seite des IB-Fenster wählen haben und sobald Sie das getan haben, können Sie den Abwickler segue ein Storyboard-ID geben:

    enter image description here

    Normalerweise verwende ich den Namen des Abwicklungssegments für die Storyboard-ID, aber Sie können verwenden, was Sie wollen. Jetzt

  5. , nachdem er das getan, Ihre Warnung vor Ansicht, die die Segue aufrufen kann:

    - (IBAction)didTouchUpInsideButton:(id)sender 
    { 
        [[[UIAlertView alloc] initWithTitle:nil message:@"go home" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK", nil] show]; 
    } 
    
    #pragma mark - UIAlertViewDelegate 
    
    - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex 
    { 
        if (buttonIndex != [alertView cancelButtonIndex]) 
        { 
         [self performSegueWithIdentifier:@"unwindToTopLevel" sender:self]; 
        } 
    } 
    
+0

Vielen Dank für die grafische Antwort, es hilft sehr! Wenn Sie sich den Kommentar und die Bearbeitung meiner Frage ansehen, werden Sie feststellen, dass ich keine UIAlertView-Funktion verwende, wie Sie es demonstriert haben. In Anbetracht dessen, wie würde ich die Überfahrt durchführen? einfach kleben, wo ich den Kommentar ablege? – CaptJak

+0

OK, ich steckte es, wo ich den Kommentar oben setze, und nichts passiert. Im Log sehe ich folgendes: '- [blahViewController unrollToTopLevel:]'. Die IBAction scheint mit nichts verbunden zu sein (der Kreis daneben ist leer). Soll das irgendwo verbunden werden? – CaptJak

+0

@CaptJak Angesichts der Tatsache, dass Alert-Ansichten asynchron ausgeführt werden, möchte ich die Alerts nicht wirklich anzeigen und dann die Sichten abbrechen, während die Alerts weiterhin angezeigt werden und bevor der Benutzer sie ablehnt (funktioniert möglicherweise, wirkt aber wie ein seltsamer UI-Fluss).Ich würde es entweder so machen wie in meiner Antwort (gehe nicht weiter, bis der Benutzer auf die Schaltfläche in der Warnung tippt), oder du könntest stattdessen den 'viewDidAppear' dieses Top-Level-Controllers anzeigen lassen. (Sie könnten eine Klasseneigenschaft haben, die diktierte, ob die Warnung angezeigt werden würde oder nicht, und sie in der 'preparateForSegue' in der Steuerung _von_ setzen, die Sie seguentieren. – Rob

0

Sie könnten versuchen, [self.dismissViewControllerAnimated:YES completion:nil]; mit

self dismissViewControllerAnimated:YES completion:^{ 
    [parentViewController.navigationController popToRootViewControllerAnimated:YES]; 
} 

ersetzt glaube ich parent zu dem präsentierenden View-Controller zeigen, und Der Block bewirkt, dass der Navigationscontroller des übergeordneten Ansichtscontrollers zum Stammansicht-Controller wechselt.

1

Aus der Klasse präsentiert Sie Ihre modal Ansicht

Aufruf modal entlassen und dann Wähler nach einer gewissen Verzögerung durchzuführen und tun dann das

Hier ist der Code Probe

//Write this in the class from where you presented a modal View. 
//Call the function from modal class when you want to dismiss and go to root. 
- (void) dismissAndGoToRoot { 
     [self dismissViewControllerAnimated:YES completion:nil]; 
     [self performSelector:@selector(gotoRoot) withObject:nil afterDelay:0.50]; 
} 

- (void)gotoRoot { 

    [self.navigationController popToRootViewControllerAnimated:NO]; 
} 

Hier finden Sie Rufen Sie die Funktion

// genau hier ist, wo würde ich normalerweise die modale VC // hier, wo ich w ould wie all VC

[self.parentViewController dismissAndGoToRoot]; 

entlassen Wenn dies nicht dann eine Instanzvariable von parent in modaler Klasse nehmen funktioniert und zuweisen, wenn Modal-View-Controller präsentiert.

+0

Okay, ich denke, dieser Code ist richtig für mich. Ich bin mir nicht sicher, wie ich es nennen soll, weil meine UIAlertView (die, wenn sie Ihre Funktion aufrufen sollte, nicht ihre eigene Funktion ist, sondern sich im 'didSelectRowAtIndexPath' befindet). Wie würde ich dich Funktion nennen, um zu reagieren, wenn das UIAlert gelöscht wird? Ich habe meinen 'didSelectRowAtIndexPath' zu meiner Frage hinzugefügt – CaptJak

+0

@CaptJak siehe editierte Antwort. –