dismissModalViewController E di passare i dati

Ho due view controller, firstViewController e secondViewController. Sto usando questo codice per passare alla mia secondViewController (sto passando una stringa):

secondViewController *second = [[secondViewController alloc] initWithNibName:nil bundle:nil];

second.myString = @"This text is passed from firstViewController!";

second.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;

[self presentModalViewController:second animated:YES];

[second release];

Ho quindi utilizzare questo codice secondViewController per tornare al firstViewController:

[self dismissModalViewControllerAnimated:YES];

Tutto questo funziona bene. La mia domanda è, come faccio a passare i dati al firstViewController? Vorrei passare una stringa diversa in firstViewController dal secondViewController.

InformationsquelleAutor Andrew Davis | 2011-06-01



4 Replies
  1. 142

    È necessario utilizzare il delegato protocolli… Ecco come fare:

    Dichiarare un protocollo nella secondViewController del file di intestazione. Dovrebbe assomigliare a questo:

    #import <UIKit/UIKit.h>
    
    @protocol SecondDelegate <NSObject>
    -(void)secondViewControllerDismissed:(NSString *)stringForFirst
    @end
    
    
    @interface SecondViewController : UIViewController
    {
        id myDelegate;  
    }
    
    @property (nonatomic, assign) id<SecondDelegate>    myDelegate;

    Non dimenticate di sintetizzare il myDelegate nell’implementazione (SecondViewController.m) file:

    @synthesize myDelegate;

    Nel FirstViewController file di intestazione dell’sottoscrivere il SecondDelegate protocollo in questo modo:

    #import "SecondViewController.h"
    
    @interface FirstViewController:UIViewController <SecondDelegate>

    Ora, quando si crea un’istanza di SecondViewController in FirstViewController si deve procedere come segue:

    //If you're using a view controller built with Interface Builder.
    SecondViewController *second = [[SecondViewController alloc] initWithNibName:"SecondViewController" bundle:[NSBundle mainBundle]];
    //If you're using a view controller built programmatically.
    SecondViewController *second = [SecondViewController new]; //Convenience initializer that uses alloc] init]
    second.myString = @"This text is passed from firstViewController!";
    second.myDelegate = self;
    second.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
    [self presentModalViewController:second animated:YES];
    [second release];

    Infine, nel file di implementazione per il primo controller di visualizzazione (FirstViewController.m) l’attuazione delle SecondDelegate metodo per secondViewControllerDismissed:

    - (void)secondViewControllerDismissed:(NSString *)stringForFirst
    {
        NSString *thisIsTheDesiredString = stringForFirst; //And there you have it.....
    }

    Ora, quando si sta per chiudere il secondo controller di visualizzazione che si desidera richiamare il metodo implementato nella prima view controller. Questa parte è semplice. Tutto quello che devi fare è, nella tua seconda view controller, aggiungere un po ‘ di codice prima di chiudere il codice:

    if([self.myDelegate respondsToSelector:@selector(secondViewControllerDismissed:)])
    {
        [self.myDelegate secondViewControllerDismissed:@"THIS IS THE STRING TO SEND!!!"];
    }
    [self dismissModalViewControllerAnimated:YES];

    Delegato protocolli sono molto, MOLTO, MOLTO utile. Fai bene a familiarizzare con loro 🙂

    NSNotifications sono un altro modo per farlo, ma, come best practice, io preferisco usarlo quando voglio comunicare su più viewControllers o oggetti. Ecco una risposta che ho postato prima, se siete curiosi di sapere utilizzando NSNotifications: La generazione degli eventi attraverso più viewcontrollers da un thread in appdelegate

    EDIT:

    Se si desidera passare più argomenti, il codice prima di chiudere assomiglia a questo:

    if([self.myDelegate respondsToSelector:@selector(secondViewControllerDismissed:argument2:argument3:)])
    {
        [self.myDelegate secondViewControllerDismissed:@"THIS IS THE STRING TO SEND!!!" argument2:someObject argument3:anotherObject];
    }
    [self dismissModalViewControllerAnimated:YES];

    Questo significa che il tuo SecondDelegate implementazione del metodo all’interno del vostro firstViewController sarà come:

    - (void) secondViewControllerDismissed:(NSString*)stringForFirst argument2:(NSObject*)inObject1 argument3:(NSObject*)inObject2
    {
        NSString thisIsTheDesiredString = stringForFirst;
        NSObject desiredObject1 = inObject1;
        //....and so on
    }
    • Secondo Apple View Controller Guida per la Programmazione iOS il secondViewController deve essere respinto alla presentazione view controller, non ha presentato uno.
    • Suona come non hai impostato il UITableView delegato. Potresti postare questo come una domanda, con il codice e il cerchio posteriore? Potrei essere in grado di aiutarvi.
    • qui: stackoverflow.com/q/15302219/2032708
    • Di aver perso la “seconda.myDelegate = self;” linea dalla mia risposta, ma qualcun altro ha catturato il problema, quindi spero che ora tutto bene 🙂 Ciao!!
    • La documentazione dice che la chiamata di chiudere su di sé la chiamata viene inoltrata alla presentazione view controller. Inoltre, richiamando su di sé è più pulito in questo modo non è necessario preoccuparsi di commutazione tra presentingViewController e parentViewController a seconda della versione di iOS target (5 o prima).
    • il suo un grande post. veramente aiutato.
    • Penso che dovrebbe essere molto più facile con….Blocchi!
    • Io sono d’accordo; i blocchi sono incredibilmente utili. Stavo pensando di cambiare questa risposta a blocchi di supporto a un certo punto. Tuttavia, in questo caso, ho lasciato il delegato risposta visibile per ora, perché ci dà un po ‘ più di libertà di manipolare gli oggetti, che possono essere passata nel modale. Io sono solo pigro e aggiornerà questa risposta per utilizzare i blocchi presto 🙂
    • ha funzionato come per magia, Grazie
    • grazie bro funziona per me, ma u leggermente necessario modificare. come molte cose sono cambiare. si prega di modificare
    • grazie per la chiamata. Ho intenzione di modificare il mio stackoverflow risposte per un po’:) farò del mio meglio per aggiornare loro al più presto.
    • Woking come un fascino.

  2. 40

    Potrei essere il modo fuori posto qui, ma sto iniziando a preferisco di gran lunga il blocco sintassi molto dettagliato delegato/protocollo di approccio. Se si fanno vc2 da vc1, hanno una proprietà in vc2 che si può impostare da vc1 che è un blocco!

    @property (nonatomic, copy) void (^somethingHappenedInVC2)(NSString *response);

    Poi, quando succede qualcosa in vc2 che si vuole raccontare vc1 circa, basta eseguire il blocco che si è definito in vc1!

    self.somethingHappenedInVC2(@"Hello!");

    Questo consente di inviare i dati da vc2 indietro vc1. Proprio come per magia. IMO, questo è molto più facile/più pulito dei protocolli. I blocchi sono impressionanti e hanno bisogno di essere abbracciato, per quanto possibile.

    MODIFICA – Migliorata esempio

    Supponiamo di avere un mainVC che vi vogliamo presentare un modalVC in cima temporaneamente per ottenere qualche input da un utente. In ordine al presente modalVC da mainVC, abbiamo bisogno di alloc/init all’interno del mainVC. Roba abbastanza di base. Beh, quando si fanno questo modalVC oggetto, possiamo anche impostare una proprietà di blocco su di esso che ci permette di comunicare facilmente tra i due vc oggetti. Così prendiamo l’esempio dall’alto e mettere le seguenti proprietà nel .h file di modalVC:

     @property (nonatomic, copy) void (^somethingHappenedInModalVC)(NSString *response);  

    Poi, nel nostro mainVC, dopo che abbiamo alloc/init piacerebbe un nuovo modalVC oggetto, è possibile impostare le proprietà del blocco di modalVC come questo:

    ModalVC *modalVC = [[ModalVC alloc] init];
    modalVC.somethingHappenedInModalVC = ^(NSString *response) {
         NSLog(@"Something was selected in the modalVC, and this is what it was:%@", response);
    }

    Siamo quindi basta impostare le proprietà del blocco, e la definizione di ciò che accade quando il blocco viene eseguito.

    Infine, il nostro modalVC, potremmo avere un tableViewController che è sostenuto da un dataSource array di stringhe. Una volta che una riga viene effettuata la scelta, si poteva fare qualcosa di simile a questo:

     - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
          NSString *selectedString = self.dataSource[indexPath.row];
          self.somethingHappenedInModalVC(selectedString);
     }

    E, naturalmente, ogni volta che si seleziona una riga in modalVC, stiamo andando a ottenere una console uscita dal nostro NSLog linea in mainVC. Speranza che aiuta!

    • Mi è piaciuto il tuo approccio. Potresti postare alcuni ulteriori esempi di codice
    • Sì, si prega di fornire una base di lavoro di esempio
    • Appretiate che, che!!
    • Questo dovrebbe ancora funzionare quando si utilizza storyboard? Adesso non è che non funziona per me. Appena si chiude con un lldb errore. Il principale diff. Posso vedere è la alloc del vc è ora un istanziato storyboard di flusso. MODIFICA E ho presentato prima di creare il blocco. Risolto.
    • Sono d’accordo con te 🙂 ho postato la mia risposta un bel po ‘ di tempo fa. Ora, posso passare tra l’utilizzo di blocchi / protocolli a seconda dell’utilizzo. Visto che questo thread è ancora abbastanza attivo a questo giorno, io, a un certo punto, modificare la mia risposta per includere blocchi.
    • E rubare tutti i miei punti?! 🙂
    • Ha. Io di credito, la tua risposta… che ne dici? 🙂
    • Questa risposta deve essere accettato in quanto questo porta i più intuitivi.
    • come si potrebbe fare esattamente questo blocco cosa, ma utilizzando una chiusura in swift??
    • Delle due risposte adeguate, questo è il migliore!
    • Questo è il mio metodo preferito. In swift è quindi realizzato con le chiusure. Molto meglio allora i delegati e le notifiche perché non è necessario specificare i protocolli o questi “brutti” notifica costanti. Se il nome della variabile nella presentazione vc che detiene la chiusura di nizza può essere molto intuitiva codice di esempio. Vc.didCancel, vc.didFinish… È possibile impostare questi prepareForSegue f vc che la presenta (se si utilizza sfocia).

  3. 4

    hmm, cerca per il centro notifiche e passa indietro le informazioni nella notifica. qui ci sono le mele prendere su di esso
    – Ho un approccio di questo tipo, personalmente, a meno che uno ha altri suggerimenti

    • Il link in realtà over-corsica, tutto ciò che serve è un osservatore (prima View Controller) e inviare la notifica dal secondo. È possibile assegnare i selettori di una notifica e di ottenere la comunicazione dei dati attraverso la notifica anche.
  4. 2

    Definire un delegato del protocollo nella seconda view controller e fare la prima parte del delegato del secondo.

Lascia un commento