6

ho provato un paio di risposte su questo sito, ma nessuno di loro sembra mettere in relazione al mio problemaRespingendo entrambe le viste UINavigation e vista modale in una sola volta a livello di codice

Ho un app MasterDetail, che ha due tipi di segues che Sto usando. Quando si preme un pulsante nella vista di dettaglio, viene utilizzato un push-down e viene visualizzata un'altra vista di dettaglio. Nella nuova vista dei dettagli (quella appena accennata) c'è un pulsante che richiama un altro UIView (foglio di modulo) usando un passaggio modale.

Quello che sto cercando di fare è quando l'utente seleziona una riga, un UIAlertView apparirà la visualizzazione di un messaggio, mentre allo stesso tempo (non deve essere allo stesso tempo) respinge l'UIViewController (modale) e torna dal Viewcontroller che è stato inserito. Fondamentalmente, devo essere in grado di eliminare tutti i viewcontrollers, uno modale e uno push (nav) in modo che la vista ritorni alla schermata principale originale con cui hanno iniziato.

Ho il UIAlertView funziona bene e posso ottenere il modal viewcontroller da respingere utilizzando [self.dismissViewControllerAnimated:YES completion:nil]; ma non so come chiudere il prossimo Viewcontroller (che si trova in un controller di navigazione). L'utilizzo di questo: [self.navigationController popToRootViewControllerAnimated:NO]; non funziona.

Qui è dove voglio chiamare la funzione per rimuovere tutte le viste:

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

Quali versioni iOS stai sostenendo? Se iOS 6 e versioni successive, solo, è possibile utilizzare unwind segues, che lo fanno molto bene. – Rob

+0

@Rob Sto usando iOS6 – CaptJak

+0

Che sensazione quando ho trovato risposta alla mia domanda nella TUA domanda. Molte grazie. –

risposta

14

Se lo si desidera, nei progetti iOS 6.0 (e successivi) è possibile utilizzare una sequenza di svolgimento.Ad esempio, è possibile:

  1. Nel vostro top controller di vista di livello (quello che si desidera rilassarsi -, non il controller si sta andando per rilassarsi da), scrivere un metodo segue rilassarsi, in questo caso chiamato unwindToTopLevel (personalmente, lo trovo utile se la segue reca qualche indicazione su ciò che la destinazione del segue è, per ragioni che diverranno evidenti quando arriviamo al punto 3, in basso):

    - (IBAction)unwindToTopLevel:(UIStoryboardSegue *)segue 
    { 
        NSLog(@"%s", __FUNCTION__); 
    } 
    
  2. Nella scena Interface Builder da cui ch si avvia la rilassarsi, controllo ⌘ -Trascinare dall'icona View Controller all'icona uscita per creare la segue di svolgimento:

    enter image description here

    In genere ci si definiscono la segue da un pulsante per l'uscita outlet (e il gioco è fatto), ma se vuoi invocare i passaggi a livello di codice, potresti volerlo creare tra il controller e la presa di svolgimento, come mostrato sopra.

  3. si otterrà un po 'di pop-up che include il nome dei tuoi segues di svolgimento (dal controller presentano ... è come una magia):

    enter image description here

  4. Se avete intenzione di invocare che segue a livello di codice, è necessario selezionare che segue Rilassatevi nella struttura del documento sul lato sinistro della finestra di IB e una volta che hai fatto, si può dare di svolgimento segue un id storyboard:

    enter image description here

    Generalmente uso il nome della sequenza di svolgimento per l'id dello storyboard, ma puoi usare quello che vuoi.

  5. Ora, dopo aver fatto questo, la vista avviso può invocare la segue:

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

Grazie per la risposta grafica, aiuta molto! Se guardi il commento e la modifica alla mia domanda, vedrai che non sto usando una funzione UIAlertView come hai dimostrato. Detto questo, come potrei eseguire il seguito? basta incollarlo dove metto il commento? – CaptJak

+0

OK, l'ho bloccato dove ho inserito il commento sopra, e non succede nulla. Nel registro vedo questo: '- [blahViewController unwindToTopLevel:]'. IBAction non sembra essere collegato a nulla (il cerchio accanto è vuoto). Questo dovrebbe essere collegato da qualche parte? – CaptJak

+0

@CaptJak Dato che le visualizzazioni di avviso vengono eseguite in modo asincrono, non vorrei realmente mostrare avviso e quindi iniziare a respingere le viste mentre l'avviso è ancora mostrato e prima che l'utente lo abbia respinto (potrebbe funzionare, ma sembra un flusso di un'interfaccia utente dispari).Lo farei o come nella mia risposta (non seguire fino a quando l'utente non tocca il pulsante in allerta), oppure potresti avere il 'viewDidAppear' di quel controller di primo livello che mostra l'avviso, invece. (potresti avere una proprietà di classe che ha dettato se l'avviso sarebbe stato mostrato o meno, e impostarlo nel 'prepareForSegue' nel controller _from_ che stai seguendo. – Rob

0

Si potrebbe provare a sostituire [self.dismissViewControllerAnimated:YES completion:nil]; con

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

Credo parentViewController punterà al controller della vista presentazione, e il blocco farà sì che il controller di navigazione del controllore della vista genitore compaia sul controller della vista radice.

1

Dalla classe che si presentato vostra vista modale

chiamata respingere di modale e quindi eseguire di selezione con un certo ritardo e poi fare il

Ecco il codice di esempio

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

Qui chiama la funzione

// proprio qui è dove vorrei normalmente chiudere il modale VC // qui è dove sono ould voler eliminare tutti VC

[self.parentViewController dismissAndGoToRoot]; 

Se questo non funziona poi prendere una variabile di ParentViewController esempio in classe modale e assegnare nel presentare controller di vista modale.

+0

Va bene, penso che questo codice sia corretto per me. Non sono sicuro di come chiamarlo, perché il mio UIAlertView (che, una volta chiuso, dovrebbe chiamare la tua funzione) non è una sua funzione, ma è in "didSelectRowAtIndexPath". Come potrei chiamare la funzione per reagire quando UIAlert è cancellato? Ho aggiunto il mio 'didSelectRowAtIndexPath' alla mia domanda – CaptJak

+0

@CaptJak vedi la risposta modificata. –

Problemi correlati