Musisz użyć protokołów delegata ... Oto jak to zrobić:
Zadeklaruj protokół w pliku nagłówkowym secondViewControllera. To powinno wyglądać tak:
#import <UIKit/UIKit.h>
@protocol SecondDelegate <NSObject>
-(void)secondViewControllerDismissed:(NSString *)stringForFirst
@end
@interface SecondViewController : UIViewController
{
id myDelegate;
}
@property (nonatomic, assign) id<SecondDelegate> myDelegate;
Nie zapomnij zsyntetyzować myDelegate w pliku implementacji (SecondViewController.m):
@synthesize myDelegate;
W pliku nagłówkowym FirstViewController zasubskrybuj protokół SecondDelegate, wykonując następujące czynności:
#import "SecondViewController.h"
@interface FirstViewController:UIViewController <SecondDelegate>
Teraz podczas tworzenia instancji SecondViewController w FirstViewController należy wykonać następujące czynności:
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];
Na koniec w pliku implementacji dla pierwszego kontrolera widoku (FirstViewController.m) zaimplementuj metodę SecondDelegate dla secondViewControllerDismissed:
- (void)secondViewControllerDismissed:(NSString *)stringForFirst
{
NSString *thisIsTheDesiredString = stringForFirst;
}
Teraz, gdy zamierzasz odrzucić drugi kontroler widoku, chcesz wywołać metodę zaimplementowaną w pierwszym kontrolerze widoku. Ta część jest prosta. Wszystko, co musisz zrobić, to w drugim kontrolerze widoku dodać kod przed kodem odrzucenia:
if([self.myDelegate respondsToSelector:@selector(secondViewControllerDismissed:)])
{
[self.myDelegate secondViewControllerDismissed:@"THIS IS THE STRING TO SEND!!!"];
}
[self dismissModalViewControllerAnimated:YES];
Protokoły delegatów są NIEZWYKLE, NIEZWYKLE, BARDZO przydatne. Dobrze by było, gdybyś się z nimi zapoznał :)
NSNotifications to inny sposób, aby to zrobić, ale jako najlepsze rozwiązanie wolę go używać, gdy chcę komunikować się między wieloma kontrolerami widoku lub obiektami. Oto odpowiedź, którą opublikowałem wcześniej, jeśli jesteś ciekawy korzystania z NSNotifications: Uruchamianie zdarzeń na wielu kontrolerach widoku z wątku w appdelegate
EDYTOWAĆ:
Jeśli chcesz przekazać wiele argumentów, kod przed odrzuceniem wygląda następująco:
if([self.myDelegate respondsToSelector:@selector(secondViewControllerDismissed:argument2:argument3:)])
{
[self.myDelegate secondViewControllerDismissed:@"THIS IS THE STRING TO SEND!!!" argument2:someObject argument3:anotherObject];
}
[self dismissModalViewControllerAnimated:YES];
Oznacza to, że implementacja metody SecondDelegate wewnątrz elementu firstViewController będzie teraz wyglądać następująco:
- (void) secondViewControllerDismissed:(NSString*)stringForFirst argument2:(NSObject*)inObject1 argument3:(NSObject*)inObject2
{
NSString thisIsTheDesiredString = stringForFirst;
NSObject desiredObject1 = inObject1;
}
Mógłbym być tutaj nie na miejscu, ale zaczynam o wiele bardziej preferować składnię blokową niż bardzo rozwlekłe podejście delegata / protokołu. Jeśli utworzysz vc2 z vc1, masz właściwość na vc2, którą możesz ustawić z vc1, która jest blokiem!
@property (nonatomic, copy) void (^somethingHappenedInVC2)(NSString *response);
Następnie, gdy w vc2 wydarzy się coś, o czym chcesz powiedzieć vc1, po prostu wykonaj blok zdefiniowany w vc1!
self.somethingHappenedInVC2(@"Hello!");
Pozwala to na wysyłanie danych z vc2 z powrotem do vc1. Jak magia. IMO, jest to o wiele łatwiejsze / czystsze niż protokoły. Bloki są niesamowite i należy je ogarnąć jak najwięcej.
EDYCJA - ulepszony przykład
Powiedzmy, że mamy mainVC, na którym chcemy tymczasowo zaprezentować modalVC, aby uzyskać dane wejściowe od użytkownika. Aby zaprezentować ten modalVC z mainVC, musimy go zaalokować / zainicjować wewnątrz mainVC. Całkiem podstawowe rzeczy. Cóż, kiedy tworzymy ten obiekt modalVC, możemy również ustawić na nim właściwość bloku, która pozwala nam łatwo komunikować się między oboma obiektami vc. Weźmy więc powyższy przykład i umieść następującą właściwość w pliku .h modalVC:
@property (nonatomic, copy) void (^somethingHappenedInModalVC)(NSString *response);
Następnie w naszym mainVC, po przydzieleniu / zainicjowaniu nowego obiektu modalVC, ustawiasz właściwość bloku modalVC w następujący sposób:
ModalVC *modalVC = [[ModalVC alloc] init]; modalVC.somethingHappenedInModalVC = ^(NSString *response) { NSLog(@"Something was selected in the modalVC, and this is what it was:%@", response); }
Więc po prostu ustawiamy właściwość bloku i definiujemy, co się stanie, gdy ten blok zostanie wykonany.
Wreszcie, w naszym modalVC możemy mieć tableViewController, który jest obsługiwany przez tablicę ciągów dataSource. Po dokonaniu wyboru wiersza możemy zrobić coś takiego:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { NSString *selectedString = self.dataSource[indexPath.row]; self.somethingHappenedInModalVC(selectedString); }
Oczywiście za każdym razem, gdy wybieramy wiersz w modalVC, otrzymamy wynik konsoli z naszej linii NSLog z powrotem w mainVC. Mam nadzieję, że to pomoże!
źródło
hmm, poszukaj centrum powiadomień i przekaż informacje w powiadomieniu. oto jabłka, które się tym zajmują - podchodzę do tego osobiście, chyba że ktoś ma inne sugestie
źródło
Zdefiniuj protokół delegata w drugim kontrolerze widoku i ustaw pierwszy z nich jako delegata drugiego.
źródło