Вам нужно использовать протоколы делегатов ... Вот как это сделать:
Объявите протокол в заголовочном файле вашего secondViewController. Должно получиться так:
#import <UIKit/UIKit.h>
@protocol SecondDelegate <NSObject>
-(void)secondViewControllerDismissed:(NSString *)stringForFirst
@end
@interface SecondViewController : UIViewController
{
id myDelegate;
}
@property (nonatomic, assign) id<SecondDelegate> myDelegate;
Не забудьте синтезировать myDelegate в файле своей реализации (SecondViewController.m):
@synthesize myDelegate;
В заголовочном файле FirstViewController подпишитесь на протокол SecondDelegate, выполнив следующие действия:
#import "SecondViewController.h"
@interface FirstViewController:UIViewController <SecondDelegate>
Теперь, когда вы создаете экземпляр SecondViewController в FirstViewController, вы должны сделать следующее:
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];
Наконец, в файле реализации для вашего первого контроллера представления (FirstViewController.m) реализуйте метод SecondDelegate для secondViewControllerDismissed:
- (void)secondViewControllerDismissed:(NSString *)stringForFirst
{
NSString *thisIsTheDesiredString = stringForFirst;
}
Теперь, когда вы собираетесь отклонить второй контроллер представления, вы хотите вызвать метод, реализованный в первом контроллере представления. Эта часть проста. Все, что вам нужно сделать, это добавить в свой второй контроллер представления некоторый код перед кодом отклонения:
if([self.myDelegate respondsToSelector:@selector(secondViewControllerDismissed:)])
{
[self.myDelegate secondViewControllerDismissed:@"THIS IS THE STRING TO SEND!!!"];
}
[self dismissModalViewControllerAnimated:YES];
Протоколы делегатов ЧРЕЗВЫЧАЙНО, КРАЙНЕ, ЧРЕЗВЫЧАЙНО полезны. Вам стоит с ними ознакомиться :)
NSNotifications - еще один способ сделать это, но я предпочитаю использовать его, когда хочу обмениваться данными между несколькими viewController'ами или объектами. Вот ответ, который я опубликовал ранее, если вам интересно использовать NSNotifications: событий через несколько контроллеров представления из потока в appdelegate
РЕДАКТИРОВАТЬ:
Если вы хотите передать несколько аргументов, код перед отклонением выглядит следующим образом:
if([self.myDelegate respondsToSelector:@selector(secondViewControllerDismissed:argument2:argument3:)])
{
[self.myDelegate secondViewControllerDismissed:@"THIS IS THE STRING TO SEND!!!" argument2:someObject argument3:anotherObject];
}
[self dismissModalViewControllerAnimated:YES];
Это означает, что ваша реализация метода SecondDelegate внутри вашего firstViewController теперь будет выглядеть так:
- (void) secondViewControllerDismissed:(NSString*)stringForFirst argument2:(NSObject*)inObject1 argument3:(NSObject*)inObject2
{
NSString thisIsTheDesiredString = stringForFirst;
NSObject desiredObject1 = inObject1;
}
Я мог бы быть здесь неуместным, но я начинаю предпочитать блочный синтаксис очень подробному подходу делегата / протокола. Если вы делаете vc2 из vc1, у vc2 есть свойство, которое вы можете установить из vc1, то есть блок!
@property (nonatomic, copy) void (^somethingHappenedInVC2)(NSString *response);
Затем, когда что-то происходит в vc2, о чем вы хотите сообщить vc1, просто выполните блок, который вы определили в vc1!
self.somethingHappenedInVC2(@"Hello!");
Это позволяет отправлять данные из vc2 обратно в vc1. Прямо как по волшебству. IMO, это намного проще / чище, чем протоколы. Блоки - это круто, и их нужно принимать как можно больше.
РЕДАКТИРОВАТЬ - Улучшенный пример
Допустим, у нас есть mainVC, над которым мы хотим временно представить модальныйVC, чтобы получить некоторые данные от пользователя. Чтобы представить этот модальныйVC из mainVC, нам нужно выделить / инициализировать его внутри mainVC. Довольно простые вещи. Когда мы создаем этот модальный объект VC, мы также можем установить для него свойство блока, которое позволяет нам легко взаимодействовать между обоими объектами vc. Итак, возьмем приведенный выше пример и поместим свойство follwing в файл .h modalVC:
@property (nonatomic, copy) void (^somethingHappenedInModalVC)(NSString *response);
Затем в нашем mainVC, после того, как мы разместили / инициализировали новый объект modalVC, вы устанавливаете свойство блока modalVC следующим образом:
ModalVC *modalVC = [[ModalVC alloc] init]; modalVC.somethingHappenedInModalVC = ^(NSString *response) { NSLog(@"Something was selected in the modalVC, and this is what it was:%@", response); }
Итак, мы просто устанавливаем свойство блока и определяем, что происходит при выполнении этого блока.
Наконец, в нашем modalVC мы могли бы иметь tableViewController, поддерживаемый массивом строк dataSource. После выбора строки мы можем сделать что-то вроде этого:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { NSString *selectedString = self.dataSource[indexPath.row]; self.somethingHappenedInModalVC(selectedString); }
И, конечно же, каждый раз, когда мы выбираем строку в modalVC, мы собираемся получить вывод консоли из нашей строки NSLog обратно в mainVC. Надеюсь, это поможет!
источник
хм, найдите центр уведомлений и верните информацию в уведомлении. вот яблоки берут на себя - я лично принимаю этот подход, если у кого-то нет других предложений
источник
Определите протокол делегата во втором контроллере представления и сделайте первый делегатом второго.
источник