Você precisa usar protocolos delegados ... Veja como fazer isso:
Declare um protocolo no arquivo de cabeçalho do secondViewController. Deve ser assim:
#import <UIKit/UIKit.h>
@protocol SecondDelegate <NSObject>
-(void)secondViewControllerDismissed:(NSString *)stringForFirst
@end
@interface SecondViewController : UIViewController
{
id myDelegate;
}
@property (nonatomic, assign) id<SecondDelegate> myDelegate;
Não se esqueça de sintetizar o myDelegate em seu arquivo de implementação (SecondViewController.m):
@synthesize myDelegate;
No arquivo de cabeçalho do seu FirstViewController, inscreva-se no protocolo SecondDelegate fazendo o seguinte:
#import "SecondViewController.h"
@interface FirstViewController:UIViewController <SecondDelegate>
Agora, ao instanciar SecondViewController em FirstViewController, você deve fazer o seguinte:
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];
Por último, no arquivo de implementação do seu primeiro controlador de visualização (FirstViewController.m), implemente o método SecondDelegate para secondViewControllerDismissed:
- (void)secondViewControllerDismissed:(NSString *)stringForFirst
{
NSString *thisIsTheDesiredString = stringForFirst;
}
Agora, quando você está prestes a dispensar o segundo controlador de visualização, deseja invocar o método implementado no primeiro controlador de visualização. Esta parte é simples. Tudo o que você faz é, em seu segundo controlador de visualização, adicionar algum código antes de dispensar o código:
if([self.myDelegate respondsToSelector:@selector(secondViewControllerDismissed:)])
{
[self.myDelegate secondViewControllerDismissed:@"THIS IS THE STRING TO SEND!!!"];
}
[self dismissModalViewControllerAnimated:YES];
Os protocolos de delegação são EXTREMAMENTE, EXTREMAMENTE, EXTREMAMENTE úteis. Seria bom se familiarizar com eles :)
NSNotifications são outra maneira de fazer isso, mas como prática recomendada, prefiro usá-lo quando quero me comunicar entre vários viewControllers ou objetos. Aqui está uma resposta que postei anteriormente se você estiver curioso sobre como usar NSNotifications: Eventos de disparo em vários controladores de visualização de um thread no appdelegate
EDITAR:
Se você quiser passar vários argumentos, o código antes de dispensar terá a seguinte aparência:
if([self.myDelegate respondsToSelector:@selector(secondViewControllerDismissed:argument2:argument3:)])
{
[self.myDelegate secondViewControllerDismissed:@"THIS IS THE STRING TO SEND!!!" argument2:someObject argument3:anotherObject];
}
[self dismissModalViewControllerAnimated:YES];
Isso significa que a implementação do método SecondDelegate dentro do firstViewController será semelhante a:
- (void) secondViewControllerDismissed:(NSString*)stringForFirst argument2:(NSObject*)inObject1 argument3:(NSObject*)inObject2
{
NSString thisIsTheDesiredString = stringForFirst;
NSObject desiredObject1 = inObject1;
}
Eu poderia estar muito fora do lugar aqui, mas estou começando a preferir muito mais a sintaxe de bloco à abordagem muito prolixa de delegado / protocolo. Se você fizer vc2 a partir de vc1, tenha uma propriedade em vc2 que você pode definir a partir de vc1 que é um bloco!
@property (nonatomic, copy) void (^somethingHappenedInVC2)(NSString *response);
Então, quando algo acontecer em vc2 que você deseja informar a vc1, apenas execute o bloco que você definiu em vc1!
self.somethingHappenedInVC2(@"Hello!");
Isso permite que você envie dados de vc2 de volta para vc1. Como mágica. IMO, isso é muito mais fácil / mais limpo do que protocolos. Os blocos são fantásticos e precisam ser adotados o máximo possível.
EDIT - exemplo aprimorado
Digamos que temos um mainVC ao qual desejamos apresentar um modalVC temporariamente para obter alguma entrada de um usuário. Para apresentar esse VC modal de mainVC, precisamos alocá-lo / iniciá-lo dentro de mainVC. Coisas bem básicas. Bem, quando fazemos este objeto VC modal, também podemos definir uma propriedade de bloco nele que nos permite comunicar facilmente entre os dois objetos vc. Então, vamos pegar o exemplo acima e colocar a propriedade a seguir no arquivo .h do modalVC:
@property (nonatomic, copy) void (^somethingHappenedInModalVC)(NSString *response);
Então, em nosso mainVC, depois de alocar / inicializar um novo objeto modalVC, você define a propriedade block de modalVC assim:
ModalVC *modalVC = [[ModalVC alloc] init]; modalVC.somethingHappenedInModalVC = ^(NSString *response) { NSLog(@"Something was selected in the modalVC, and this is what it was:%@", response); }
Portanto, estamos apenas configurando a propriedade do bloco e definindo o que acontece quando esse bloco é executado.
Finalmente, em nosso modalVC, poderíamos ter um tableViewController que é apoiado por um array dataSource de strings. Depois de fazer uma seleção de linha, poderíamos fazer algo assim:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { NSString *selectedString = self.dataSource[indexPath.row]; self.somethingHappenedInModalVC(selectedString); }
E, claro, cada vez que selecionarmos uma linha em modalVC, obteremos uma saída de console de nossa linha NSLog de volta em mainVC. Espero que ajude!
fonte
hmm, procure a central de notificações e devolva informações em uma notificação. aqui está as maçãs - eu considero essa abordagem pessoalmente, a menos que alguém tenha alguma outra sugestão
fonte
Defina um protocolo de delegado no segundo controlador de visão e torne o primeiro o delegado do segundo.
fonte