Vous devez utiliser des protocoles de délégation ... Voici comment procéder:
Déclarez un protocole dans le fichier d'en-tête de votre secondViewController. Ça devrait ressembler à ça:
#import <UIKit/UIKit.h>
@protocol SecondDelegate <NSObject>
-(void)secondViewControllerDismissed:(NSString *)stringForFirst
@end
@interface SecondViewController : UIViewController
{
id myDelegate;
}
@property (nonatomic, assign) id<SecondDelegate> myDelegate;
N'oubliez pas de synthétiser le myDelegate dans votre fichier d'implémentation (SecondViewController.m):
@synthesize myDelegate;
Dans le fichier d'en-tête de votre FirstViewController, abonnez-vous au protocole SecondDelegate en procédant comme suit:
#import "SecondViewController.h"
@interface FirstViewController:UIViewController <SecondDelegate>
Maintenant, lorsque vous instanciez SecondViewController dans FirstViewController, vous devez effectuer les opérations suivantes:
SecondViewController *second = [[SecondViewController alloc] initWithNibName:"SecondViewController" bundle:[NSBundle mainBundle]];
SecondViewController *second = [SecondViewController new];
second.myString = @"This text is passed from firstViewController!";
second.myDelegate = self;
second.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentModalViewController:second animated:YES];
[second release];
Enfin, dans le fichier d'implémentation de votre premier contrôleur de vue (FirstViewController.m), implémentez la méthode de SecondDelegate pour secondViewControllerDismissed:
- (void)secondViewControllerDismissed:(NSString *)stringForFirst
{
NSString *thisIsTheDesiredString = stringForFirst;
}
Maintenant, lorsque vous êtes sur le point de fermer le deuxième contrôleur de vue, vous souhaitez appeler la méthode implémentée dans le premier contrôleur de vue. Cette partie est simple. Tout ce que vous faites est, dans votre deuxième contrôleur de vue, d'ajouter du code avant le code de rejet:
if([self.myDelegate respondsToSelector:@selector(secondViewControllerDismissed:)])
{
[self.myDelegate secondViewControllerDismissed:@"THIS IS THE STRING TO SEND!!!"];
}
[self dismissModalViewControllerAnimated:YES];
Les protocoles délégués sont EXTRÊMEMENT, EXTRÊMEMENT, EXTRÊMEMENT utiles. Cela vous ferait du bien de vous familiariser avec eux :)
NSNotifications est une autre façon de faire cela, mais comme meilleure pratique, je préfère l'utiliser lorsque je souhaite communiquer sur plusieurs viewControllers ou objets. Voici une réponse que j'ai publiée plus tôt si vous êtes curieux d'utiliser NSNotifications: déclencher des événements sur plusieurs contrôleurs de vue à partir d'un fil de discussion dans l'appdelegate
ÉDITER:
Si vous souhaitez passer plusieurs arguments, le code avant de rejeter ressemble à ceci:
if([self.myDelegate respondsToSelector:@selector(secondViewControllerDismissed:argument2:argument3:)])
{
[self.myDelegate secondViewControllerDismissed:@"THIS IS THE STRING TO SEND!!!" argument2:someObject argument3:anotherObject];
}
[self dismissModalViewControllerAnimated:YES];
Cela signifie que votre implémentation de méthode SecondDelegate dans votre firstViewController ressemblera maintenant à:
- (void) secondViewControllerDismissed:(NSString*)stringForFirst argument2:(NSObject*)inObject1 argument3:(NSObject*)inObject2
{
NSString thisIsTheDesiredString = stringForFirst;
NSObject desiredObject1 = inObject1;
}
Je pourrais être hors de propos ici, mais je commence à préférer de beaucoup la syntaxe de bloc à l'approche très verbeuse délégué / protocole. Si vous créez vc2 à partir de vc1, ayez une propriété sur vc2 que vous pouvez définir à partir de vc1 qui est un bloc!
@property (nonatomic, copy) void (^somethingHappenedInVC2)(NSString *response);
Ensuite, quand quelque chose se passe dans vc2 dont vous voulez parler à vc1, exécutez simplement le bloc que vous avez défini dans vc1!
self.somethingHappenedInVC2(@"Hello!");
Cela vous permet de renvoyer les données de vc2 vers vc1. Tout comme la magie. IMO, c'est beaucoup plus facile / plus propre que les protocoles. Les blocs sont géniaux et doivent être adoptés autant que possible.
EDIT - Exemple amélioré
Disons que nous avons un mainVC sur lequel nous voulons présenter temporairement un modalVC pour obtenir une entrée d'un utilisateur. Afin de présenter ce modalVC de mainVC, nous devons l'allouer / l'initier à l'intérieur de mainVC. Des trucs assez basiques. Eh bien, lorsque nous créons cet objet modalVC, nous pouvons également définir une propriété de bloc qui nous permet de communiquer facilement entre les deux objets vc. Prenons donc l'exemple ci-dessus et mettons la propriété follwing dans le fichier .h de modalVC:
@property (nonatomic, copy) void (^somethingHappenedInModalVC)(NSString *response);
Ensuite, dans notre mainVC, après avoir alloué / initié un nouvel objet modalVC, vous définissez la propriété block de modalVC comme ceci:
ModalVC *modalVC = [[ModalVC alloc] init]; modalVC.somethingHappenedInModalVC = ^(NSString *response) { NSLog(@"Something was selected in the modalVC, and this is what it was:%@", response); }
Nous définissons donc simplement la propriété du bloc et définissons ce qui se passe lorsque ce bloc est exécuté.
Enfin, dans notre modalVC, nous pourrions avoir un tableViewController qui est soutenu par un tableau dataSource de chaînes. Une fois qu'une sélection de ligne est faite, nous pourrions faire quelque chose comme ceci:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { NSString *selectedString = self.dataSource[indexPath.row]; self.somethingHappenedInModalVC(selectedString); }
Et bien sûr, chaque fois que nous sélectionnons une ligne dans modalVC, nous allons récupérer une sortie console de notre ligne NSLog dans mainVC. J'espère que ça t'as aidé!
la source
hmm, recherchez le centre de notification et renvoyez les informations dans une notification. voici que les pommes le prennent - je prends cette approche personnellement à moins que quelqu'un n'ait d'autres suggestions
la source
Définissez un protocole de délégué dans le second contrôleur de vue et faites du premier le délégué du second.
la source