2013-12-17 16 views
12

So che questa domanda è stata fatta e ho risposto molte volte qui. Ma mi sto occupando di questa cosa per la prima volta e ancora non riesco a ottenere la perfetta implementazione di ciò nella mia mente. Ecco il codice Ho il metodo delegato che implemento per passare i dati da SecondViewController a FirstViewController.Passaggio di dati tra 2 UIViewController utilizzando delegato e protocollo

FirstViewController.h

#import "SecondViewController.h" 

@interface FirstViewController : UITableViewController<sampleDelegate> 
@end 

FirstViewController.m

@interface FirstViewController() 

// Array in which I want to store the data I get back from SecondViewController. 
@property (nonatomic, copy) NSArray *sampleData; 
@end 

@implementation FirstViewController 
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    SecondViewController *controller = [[SecondViewController alloc] init];   
    [self.navigationController pushViewController:controller animated:YES]; 
} 
@end 

SecondViewController.h

@protocol sampleDelegate <NSObject> 
- (NSArray*)sendDataBackToFirstController; 
@end 

@interface SecondViewController : UITableViewController 
@property (nonatomic, strong) id <sampleDelegate> sampleDelegateObject; 
@end 

SecondViewController.m

@interface SecondViewController() 
@property (strong, nonatomic) NSArray *dataInSecondViewController; 
@end 

@implementation SecondViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    self.dataInSecondViewController = [NSArray arrayWithObjects:@"Object1", @"Object2", nil]; 
} 

- (NSArray*)sendDataBackToFirstController 
{ 
    return self.dataInSecondViewController; 
} 
@end 

sto facendo correttamente? Tutto ciò che voglio è inviare i dati in self.dataInSecondViewController a FirstViewController e memorizzarli nella proprietà NSArraysampleData di FirstViewController.

In qualche modo non riesco ad accedere a sendDataBackToFirstController in FirstViewController. Quali altre cose mi manca implementando per accedere a sendDataBackToFirstController lì?

+1

È necessario impostare la prima vc come delegato seconda vc. Quindi il metodo delegato di seconda vc deve essere implementato in first vc. Quindi invoca il metodo dalla seconda vc quando viene attivato l'evento. Dal tuo scenario non è chiaro se vuoi avere un'origine dati o un delegato. Se si usa la seconda vc come origine dati per la prima vc, è la prima vc che richiede i dati. Ma vuoi solo restituire il valore alla prima vc quando qualche evento accade nella seconda vc quindi il suo tipo di delegato. Quindi dovresti modificare il tipo di ritorno in null e passare i dati come argomento. – Anupdas

+0

corretto. Ho provato a fare controller.delegate = self in didSelectRow ... del mio First vc. Ma in qualche modo il controller non è in grado di trovare l'oggetto delegato. Il mio codice sembra essere corretto finora? –

+0

Si prega di seguire le risposte di @gdavis e art – Anupdas

risposta

8

Non proprio corretto. Innanzitutto è necessario assegnare la proprietà delegato nel primo controller della vista in modo che il secondo controller della vista sappia a quale oggetto inviare messaggi.

FirstViewController.m

controller.delegate = self; 

In secondo luogo, si ha l'invio e la ricezione del vostro metodo delegato all'indietro. È stato configurato in modo che il FirstViewController possa chiamare sendDataBackToFirstController sul secondo controller. In un modello delegato, SecondViewController è quello che invia il messaggio e, facoltativamente, invia i dati con tale metodo.Quindi, si dovrebbe cambiare la vostra dichiarazione delegato a qualcosa di simile:

@protocol sampleDelegate <NSObject> 
- (void)secondControllerFinishedWithItems:(NSArray*)newData; 
@end 

Poi, quando il SecondViewController ha completato le sue attività e ha bisogno di comunicare il suo delegato, dovrebbe fare qualcosa di simile:

// ... do a bunch of tasks ... 
// notify delegate 
if ([self.delegate respondsToSelector:@selector(secondControllerFinishedWithItems:)]) { 
    [self.delegate secondControllerFinishedWithItems:arrayOfNewData]; 
} 

I aggiunta un'istruzione extra if qui per verificare che il delegato risponda al metodo che vogliamo inviare prima di inviarlo effettivamente. Se avessimo metodi opzionali nel nostro protocollo e non avessimo questo, l'app si arresterebbe in modo anomalo.

Spero che questo aiuti!

+0

La spiegazione di @ e @art mi ha aiutato molto a comprendere l'intero flusso del protocollo e dei delegati. Ho seguito il tuo codice e il codice dell'arte per implementare i delegati e ho ottenuto ciò che volevo. Ho modificato la proprietà delegato a deboli anziché forti per impedire il ciclo di conservazione. L'implementazione del protocollo –

1

Primo cambio @property (nonatomic, strong) id <sampleDelegate> sampleDelegateObject; a @property (nonatomic, weak) id <sampleDelegate> sampleDelegateObject; per prevenire mantenere ciclo di ricerca di Google con quella parola per la spiegazione.

Seconda il protocollo dovrebbe essere

@protocol sampleDelegate <NSObject> 
- (void)sendDataBackToFirstController:(NSArray*)dataToSendBack; 
@end 

e quando si desidera inviare i dati indietro si chiama [self.sampleDelegateObject sendDataBackToFirstControoler:yourData]; primo controller di vista deve implementare quelli metodo nel protocollo.

4

Si prega di seguire questa

FirstViewController.h

#import "SecondViewController.h" 

    @interface FirstViewController : UITableViewController<sampleDelegate> 
    @end 

FirstViewController.m

@interface FirstViewController() 

    // Array in which I want to store the data I get back from SecondViewController. 
    @property (nonatomic, copy) NSArray *sampleData; 
    @end 

@implementation FirstViewController 
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    SecondViewController *controller = [[SecondViewController alloc] init]; 
    controller.sampleDelegateObject=self;  
    [self.navigationController pushViewController:controller animated:YES]; 

} 

    //implementation of delegate method 
    - (NSArray*)sendDataBackToFirstController 
{ 
    return self.dataInSecondViewController; 
} 
@end 

SecondViewController.h

@protocol sampleDelegate <NSObject> 
- (NSArray*)sendDataBackToFirstController; 
@end 

@interface SecondViewController : UITableViewController 
@property (nonatomic, strong) id <sampleDelegate> sampleDelegateObject; 
@end 
SecondViewController.m 

@interface SecondViewController() 
@property (strong, nonatomic) NSArray *dataInSecondViewController; 
@end 

@implementation SecondViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    self.dataInSecondViewController = [NSArray arrayWithObjects:@"Object1", @"Object2", nil]; 
    //calling the delegate method 
    [sampleDelegateObject sendDataBackToFirstController]; 
} 


    @end 
+1

sarà nella classe in cui si desidera implementare –

+0

Grazie per le informazioni dettagliate con il codice. –

Problemi correlati