2013-12-17 17 views
12

Ich weiß, dass diese Frage wurde hier mehrmals gestellt und beantwortet. Aber ich habe es zum ersten Mal mit diesem Ding zu tun und kann es immer noch nicht perfekt umsetzen. Hier ist der Code Ich habe die Delegate-Methode, die ich implementieren, um Daten von SecondViewController zu FirstViewController zu übergeben.Übergeben von Daten zwischen 2 UIViewController mit Delegaten und Protokoll

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 

Bin ich es richtig gemacht? Alles was ich will ist es die Daten in self.dataInSecondViewController an FirstViewController zu senden und dort in der NSArray Eigenschaft sampleData von FirstViewController zu speichern.

Irgendwie kann ich sendDataBackToFirstController in FirstViewController nicht zugreifen. Welche anderen Dinge vermisse ich, um dort auf sendDataBackToFirstController zuzugreifen?

+1

Sie müssen die erste vc als Delegierter setzen zweite vc. Daher muss die Delegate-Methode von second vc in der ersten vc implementiert werden. Rufen Sie dann die Methode von second vc auf, wenn das Ereignis ausgelöst wird. Aus Ihrem Szenario ist unklar, ob Sie eine Datenquelle oder einen Delegaten haben möchten. Wenn Sie eine zweite VC als Datenquelle für die erste VC verwenden, ist dies die erste VC, die Daten anfordert. Aber Sie wollen nur den Wert zurück auf die erste vc zurückgeben, wenn ein Ereignis in der zweiten vc auftritt, dann seine Art von Delegaten. Dann müssten Sie den Rückgabetyp auf void ändern und die Daten als Argument übergeben. – Anupdas

+0

Korrigieren. Ich habe versucht, controller.delegate = self in didSelectRow ... meiner ersten vc. Aber irgendwie Controller ist nicht in der Lage, das Delegat-Objekt zu finden. Scheint mein Code bis jetzt korrekt? –

+0

Bitte folgen Sie den Antworten von @gdavis und Kunst – Anupdas

Antwort

8

Nicht ganz richtig. Zuerst müssen Sie die Eigenschaft delegate im ersten View-Controller zuweisen, damit der zweite View-Controller weiß, an welches Objekt Nachrichten gesendet werden sollen.

FirstViewController.m

controller.delegate = self; 

Zweitens haben Sie rückwärts das Senden und Empfangen Ihrer Delegatmethode. Sie haben es so eingerichtet, dass der FirstViewController auf dem zweiten Controller sendDataBackToFirstController aufrufen soll. In einem Delegate-Muster sendet der SecondViewController die Nachricht und sendet optional Daten mit dieser Methode.Also, sollten Sie Ihre Delegatendeklaration zu so etwas wie dies ändern:

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

Dann, wenn Ihre SecondViewController ihre Aufgaben beendet und muss seine Delegierten benachrichtigen, es so etwas tun sollte:

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

I hat hier eine zusätzliche if-Anweisung hinzugefügt, um zu überprüfen, ob der Delegat auf die Methode reagiert, die wir senden wollen, bevor er tatsächlich gesendet wird. Wenn wir optionale Methoden in unserem Protokoll hätten und diese nicht hätten, würde die App abstürzen.

Hoffe, das hilft!

+0

Ihre und @ Art's Erklärung hat mir sehr geholfen, den gesamten Ablauf des Protokolls und der Delegierten zu verstehen. Ich habe deinen und art's Code verfolgt, um die Delegierten zu implementieren, und ich habe bekommen, was ich wollte. Ich änderte die Delegate-Eigenschaft zu schwach statt stark, um den Retain-Zyklus zu verhindern. –

1

Erster Wechsel @property (nonatomic, strong) id <sampleDelegate> sampleDelegateObject; zu @property (nonatomic, weak) id <sampleDelegate> sampleDelegateObject; verhindert Zyklus Google-Suche mit diesem Wort zur Erklärung behalten.

Zweite Ihr Protokoll sollte

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

sein und wenn Sie Daten senden möchten sichern Sie [self.sampleDelegateObject sendDataBackToFirstControoler:yourData]; erste View-Controller aufrufen müssen diejenigen Verfahren in Protokoll implementieren.

4

Bitte folgen Sie diesem

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 
+1

Protokoll-Implementierung wird in der Klasse sein, in der Sie implementieren möchten –

+0

Vielen Dank für Detailinformationen mit Code. –

Verwandte Themen