Passer des données entre 2 UIViewController en utilisant un délégué et un protocole

Je sais que cette question a été posée et répondue plusieurs fois ici. Mais je fais face à cette chose pour la première fois et je n'arrive toujours pas à get la mise en œuvre parfaite dans mon esprit. Voici le code que j'ai la méthode déléguée que SecondViewController pour passer des données de SecondViewController à FirstViewController .

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 

Est-ce que je le fais correctement? Tout ce que je veux pour envoyer datatables dans self.dataInSecondViewController à FirstViewController et le stocker là-bas dans la propriété NSArray sampleData de FirstViewController .

D'une certaine manière, je ne suis pas en mesure d'accéder à sendDataBackToFirstController dans FirstViewController . Quelles sont les autres choses que je manque implémentant pour accéder à sendDataBackToFirstController là?

Pas tout à fait juste. Vous devez d'abord affecter la propriété delegate dans le premier controller de vue afin que le deuxième controller de vue sache à quel object envoyer des messages.

FirstViewController.m

 controller.delegate = self; 

Deuxièmement, vous avez l'envoi et la réception de votre méthode de délégué en arrière. Vous l'avez installé d'une manière où le FirstViewController devrait appeler sendDataBackToFirstController sur le second controller. Dans un model de délégué, le SecondViewController est celui qui envoie le message et envoie éventuellement des données avec cette méthode. Donc, vous devriez changer votre déclaration de délégué à quelque chose comme ceci:

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

Ensuite, lorsque votre secondViewController termine ses tâches et doit notifier son délégué, il devrait faire quelque chose comme ceci:

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

J'ai ajouté une instruction if supplémentaire ici pour vérifier que le délégué répondra à la méthode que nous voulons lui envoyer avant de l'envoyer. Si nous avions des methods optionnelles dans notre protocole et que nous n'avions pas cela, l'application tomberait en panne.

J'espère que cela t'aides!

Veuillez suivre ceci

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 

Première modification @property (nonatomic, strong) id <sampleDelegate> sampleDelegateObject; à @property (nonatomic, weak) id <sampleDelegate> sampleDelegateObject; pour empêcher la search de cycle de retenue google avec ce mot pour l'explication.

Deuxièmement, votre protocole devrait être

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

et quand vous voulez renvoyer des données, vous appelez [self.sampleDelegateObject sendDataBackToFirstControoler:yourData]; Le premier controller de vue doit implémenter ces methods dans le protocole.