Передача данных между 2 UIViewController с использованием делегата и протокола

Я знаю, что этот вопрос задан и много раз ответил здесь. Но я имею дело с этой штукой в ​​первый раз и до сих пор не в состоянии добиться совершенной реализации этого в моем сознании. В этом коде у меня есть метод делегата, который я реализую для передачи данных от SecondViewController до FirstViewController.

FirstViewController.h

#import "SecondViewController.h"

@interface FirstViewController : UITableViewController<sampleDelegate> 
@end

FirstViewController.m

@interface FirstViewController ()

// Array in which I want to store the data I get back from SecondViewController.
@property (nonatomic, copy) NSArray *sampleData;
@end

@implementation FirstViewController
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
   SecondViewController *controller = [[SecondViewController alloc] init];          
   [self.navigationController pushViewController:controller animated:YES];
}
@end

SecondViewController.h

@protocol sampleDelegate <NSObject>
- (NSArray*)sendDataBackToFirstController;
@end

@interface SecondViewController : UITableViewController
@property (nonatomic, strong) id <sampleDelegate> sampleDelegateObject;
@end

SecondViewController.m

@interface SecondViewController ()
@property (strong, nonatomic) NSArray *dataInSecondViewController;
@end

@implementation SecondViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.dataInSecondViewController = [NSArray arrayWithObjects:@"Object1", @"Object2", nil];
}

- (NSArray*)sendDataBackToFirstController
{
    return self.dataInSecondViewController;
}
@end

Я делаю это правильно? Все, что я хочу, чтобы он отправил данные в self.dataInSecondViewController в FirstViewController и сохранил их там в свойстве NSArray sampleData FirstViewController.

Как-то я не могу получить доступ к sendDataBackToFirstController в FirstViewController. Какие еще вещи мне не хватает для доступа к sendDataBackToFirstController там?

Ответ 1

Не совсем верно. Сначала вам нужно назначить свойство делегата в первом контроллере представления, чтобы второй контроллер представления знал, к какому объекту отправляться сообщения.

FirstViewController.m

controller.delegate = self;

Во-вторых, вы отправляете и получаете свой метод делегата назад. У вас есть настройка таким образом, что ожидается, что FirstViewController вызовет sendDataBackToFirstController на втором контроллере. В шаблоне делегата SecondViewController - это тот, который отправляет сообщение и, необязательно, отправляет данные с этим методом. Итак, вы должны изменить объявление делегата на что-то вроде этого:

@protocol sampleDelegate <NSObject>
- (void)secondControllerFinishedWithItems:(NSArray* )newData;
@end

Затем, когда ваш SecondViewController завершит выполнение своих задач и должен уведомить своего делегата, он должен сделать что-то вроде этого:

// ... do a bunch of tasks ...
// notify delegate
if ([self.delegate respondsToSelector:@selector(secondControllerFinishedWithItems:)]) {
    [self.delegate secondControllerFinishedWithItems:arrayOfNewData];
}

Я добавил здесь дополнительную инструкцию if, чтобы проверить, будет ли делегат отвечать на метод, который мы хотим отправить, прежде чем отправлять его. Если бы у нас были факультативные методы в нашем протоколе и не было этого, приложение потерпит крах.

Надеюсь, это поможет!

Ответ 2

Пожалуйста, следуйте этому

FirstViewController.h

   #import "SecondViewController.h"

   @interface FirstViewController : UITableViewController<sampleDelegate> 
   @end

FirstViewController.m

  @interface FirstViewController ()

  // Array in which I want to store the data I get back from SecondViewController.
  @property (nonatomic, copy) NSArray *sampleData;
  @end

 @implementation FirstViewController
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
 {
   SecondViewController *controller = [[SecondViewController alloc] init]; 
   controller.sampleDelegateObject=self;      
  [self.navigationController pushViewController:controller animated:YES];

 }

  //implementation of delegate method
  - (NSArray*)sendDataBackToFirstController
{
  return self.dataInSecondViewController;
}
 @end

SecondViewController.h

 @protocol sampleDelegate <NSObject>
- (NSArray*)sendDataBackToFirstController;
@end

@interface SecondViewController : UITableViewController
@property (nonatomic, strong) id <sampleDelegate> sampleDelegateObject;
@end
SecondViewController.m

 @interface SecondViewController ()
 @property (strong, nonatomic) NSArray *dataInSecondViewController;
 @end

 @implementation SecondViewController

 - (void)viewDidLoad
{
  [super viewDidLoad];
  self.dataInSecondViewController = [NSArray arrayWithObjects:@"Object1", @"Object2", nil];
   //calling the delegate method
  [sampleDelegateObject sendDataBackToFirstController];
}


  @end

Ответ 3

Первое изменение @property (nonatomic, strong) id <sampleDelegate> sampleDelegateObject; до @property (nonatomic, weak) id <sampleDelegate> sampleDelegateObject;, чтобы предотвратить сохранение цикла поиска Google с этим словом для объяснения.

Во-вторых ваш протокол должен быть

@protocol sampleDelegate <NSObject>
- (void)sendDataBackToFirstController:(NSArray*)dataToSendBack;
@end

и когда вы хотите отправить данные назад, вы вызываете [self.sampleDelegateObject sendDataBackToFirstControoler:yourData];, контроллер первого представления должен реализовать этот метод в протоколе.