83 votes

dismissModalViewController ET au transfert des données

J'ai deux contrôleurs de vue, firstViewController et secondViewController. J'utilise ce code pour passer mon secondViewController (je suis aussi du passage d'une chaîne à elle):

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

Je puis utiliser ce code dans secondViewController pour revenir à la firstViewController:

[self dismissModalViewControllerAnimated:YES];

Tout cela fonctionne très bien. Ma question est, comment pourrais-je transmettre des données à la firstViewController? Je voudrais passer à une autre chaîne dans le firstViewController de la secondViewController.

J'apprécie toute l'aide. Merci les gars.

141voto

Sid Points 6025

Vous avez besoin d'utiliser délégué de protocoles... Voici comment faire:

Déclarer un protocole dans votre secondViewController du fichier d'en-tête. Il devrait ressembler à ceci:

#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 faire la synthèse de la myDelegate dans votre .m fichier:

@synthesize myDelegate;

Dans votre firstViewController du fichier d'en-tête abonnez-vous à la SecondDelegate protocole en faisant ceci:

#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:nil bundle:nil];

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

second.myDelegate = self;

second.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;

[self presentModalViewController:second animated:YES];

[second release];

Enfin, dans le .m de fichier pour votre premier point de vue contrôleur de mettre en œuvre les SecondDelegate méthode de secondViewControllerDismissed:

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

Maintenant, quand vous êtes sur le point de rejeter le second point de vue contrôleur que vous souhaitez invoquer la méthode mise en œuvre dans la première vue-contrôleur. Cette partie est simple. Tout ce que vous faites est, dans votre seconde vue-contrôleur, ajouter un peu de code avant de le rejeter code:

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

Délégué protocoles sont EXTRÊMEMENT, extrêmement, EXTRÊMEMENT utile. Cela vous ferait du bien de vous familiariser avec eux :)

NSNotifications sont une autre façon de le faire, mais comme une meilleure pratique, je préfère l'utiliser quand je veux communiquer à travers de multiples viewControllers ou des objets. Voici une réponse que j'ai posté plus tôt si vous êtes curieux à propos de l'utilisation NSNotifications: de déclencher des événements dans plusieurs viewcontrollers à partir d'un thread dans le appdelegate

EDIT:

Si vous souhaitez passer plusieurs arguments, le code avant de licencier 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 SecondDelegate méthode de la mise en œuvre à l'intérieur de votre firstViewController va ressembler à ça:

- (void) secondViewControllerDismissed:(NSString*)stringForFirst argument2:(NSObject*)inObject1 argument3:(NSObject*)inObject2
{
    NSString thisIsTheDesiredString = stringForFirst;
    NSObject desiredObject1 = inObject1;
    //....and so on
}

40voto

Lizza Points 814

J'ai peut être moyen de sortir de la place ici, mais je préfère de beaucoup le bloc de syntaxe à la très prolixe délégué/approche du protocole. Si vous faites vc2 de vc1, ont une propriété sur vc2 que vous pouvez définir à partir de vc1 qui est un bloc!

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

Puis, quand il se passe quelque chose dans vc2 que vous voulez dire vc1, exécuter le bloc que vous avez définis dans vc1!

self.somethingHappenedInVC2(@"Hello!");

Cela vous permet d'envoyer des données à partir vc2 retour à la vc1. Comme par magie. IMO, c'est beaucoup plus facile/plus propres que les protocoles. Les blocs sont impressionnantes et ont besoin d'être embrassé autant que possible.

EDIT - Amélioration de l'exemple

Disons que nous avons un mainVC que nous voulons présenter un modalVC sur le dessus de temporairement pour obtenir une entrée d'un utilisateur. Afin de présenter cette modalVC de mainVC, nous avons besoin d'alloc/init à l'intérieur de mainVC. De jolis trucs de base. Eh bien, lorsque nous faisons cette modalVC objet, on peut également définir une propriété de bloc qui nous permet de communiquer facilement entre les deux vc objets. Donc, nous allons prendre l'exemple ci-dessus et mettre le prédécesseur de la propriété dans le .h fichier de modalVC:

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

Ensuite, dans notre mainVC, après nous avons alloc/init avais un nouveau modalVC objet, vous pouvez définir la propriété de bloc 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 sommes donc tout simplement le réglage de la propriété de bloc, et la définition de ce qui se passe lorsque ce bloc est exécuté.

Enfin, dans notre modalVC, nous pourrions avoir un tableViewController qui est soutenue par une source de données tableau de chaînes de caractères. Une fois une ligne de sélection 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 avons sélectionnez une ligne dans modalVC, nous allons arriver à une sortie de la console à partir de notre NSLog ligne de retour dans mainVC. Espérons que ça aide!

4voto

burrows111 Points 462

hmm, recherchez le centre de notification et de transmettre des informations dans une notification. voici les pommes de prendre sur elle - Je prendre cette approche personnellement, sauf si quelqu'un a d'autres suggestions

2voto

cschwarz Points 390

Définir un délégué du protocole dans le second contrôleur et de faire le premier le délégué de la seconde.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X