2011-03-09 79 views
14

我一直在爭奪兩個視圖控制器之間傳遞數據兩天,現在變得非常困惑。我是Objective-C的新手,並且發現了一些棘手的部分讓我頭暈目眩。使用委託來傳遞數據備份導航堆棧

我有一個導航控制器,FirstView是一個窗體,並且在這個窗體上我有一個加載SecondView的按鈕,它包含一個TableView供用戶選擇一些選項。然後我想通過選擇回的firstView控制器和顯示數據等..

我已經閱讀了很多關於這個(計算器,iphonedevsdk,CS 193P資源)和我見過的選項,

1)在應用程序委託伊娃(骯髒和不推薦) 2)創建一個單獨 3)創建數據模型類 4)使用的協議和代表(由蘋果推薦)

我想要做正確的事情並希望使用選項4 - 我的程序中的代表

問題是,我不理解代表以及如何設置和實施它們。

任何人都可以提供一個關於如何使用代理和2視圖控制器設置和傳遞NSArray的基本示例。

在此先感謝 馬特

回答

29

代表團是在這種情況下要使用正確的模式,但因爲它是使用全局變量您的描述不看很像代表團。也許你正在將全局變量存儲在你的App Delegate中,你應該儘量避免。

這裏的代碼應該是什麼樣一個大致的輪廓:

SecondViewController.h

@protocol SecondViewControllerDelegate; 

@interface SecondViewController; 

SecondViewController : UIViewController 
{ 
    id<SecondViewControllerDelegate> delegate; 

    NSArray* someArray; 
} 

@property (nonatomic, assign) id<SecondViewControllerDelegate> delegate; 
@property (nonatomic, retain) NSArray* someArray; 

@end 

@protocol SecondViewControllerDelegate 
- (void)secondViewControllerDidFinish:(SecondViewController*)secondViewController; 
@end 

SecondViewController。米

@implementation SecondViewController 

@synthesize delegate; 
@synthesize someArray; 

- (void)dealloc 
{ 
    [someArray release]; 
    [super dealloc]; 
} 

- (void)someMethodCalledWhenUserIsDone 
{ 
    [delegate secondViewControllerDidFinish:self]; 
} 

FirstViewController.h:

#import SecondViewController 

@interface FirstViewController : UIViewController <SecondViewControllerDelegate> 
{ 
    ... 
} 

@end 

FirstViewController.m

@implementation FirstViewController 

- (void)secondViewControllerDidFinish:(SecondViewController*)secondViewController 
{ 
    NSArray* someArray = secondViewController.someArray 
    // Do something with the array 
} 

@end 
+2

非常感謝您的回覆,對他人很有幫助。我還提出了另一個類似的問題,然後以完整的答案進行跟蹤。 http://stackoverflow.com/questions/5210535/passing-data-between-view-controllers – 2012-10-19 18:27:21

+0

你能告訴我如何從第一個視圖做同樣的事情到第二個像發送字符串從第一個到第二個視圖專門設置爲委託自我..?在此先感謝:) – dreamBegin 2016-09-27 08:18:25

+0

爲什麼在創建id 委託和屬性委託時給出錯誤說「現有實例變量」。?謝謝。 – MRizwan33 2018-02-23 09:22:53

1

關我的頭頂。您可以用您的自定義對象替換_returnedProperty,並在setReturnedProperty方法實際分配表中的選中值之前完成所有魔術。

@interface FormController : UIViewController { 
    NSString *_returnedProperty; 
} 

@property (nonatomic, retain) NSString *returnedProperty; 

@end 

@implementation FormController 

- (void)showChoices { 
    TableController *tv = [[TableController alloc] initWithDelegate:self]; 
    [self.navigationController pushViewController:tv animated:YES]; 
    [tv release]; 
} 

- (void)setReturnedProperty:(NSString *)string { 
    NSLog(@"Setting property as a delegate"); 
    [_returnedProperty release]; 
    _returnedProperty = [string retain]; 
} 

@synthesize returnedProperty=_returnedProperty; 

@end 

@interface TableController : UITableViewController { 
    id _delegate 
} 
@end 

@implementation TableController 

- (id)initWithDelegate:(id)delegate { 
    self = [super initWithStyle:UITableViewGroupedStyle]; 
    if (!self) return nil; 

    _delegate = delegate; 
    return self; 
} 

- (void)tableView:(UITableView *)tv didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 
    // do the data retrieval stuff 
    NSString *returnedProperty = @"foo"; 
    [_delegate setReturnedProperty:returnableProperty]; 
} 

@end 
+0

感謝Elimantas,試圖實現這一點,但失敗了!這是真正的協議和委託實施?我沒有看到@protocol,也沒有看到。你在xcode中有這個代碼嗎?或者你是直接寫入答案盒? – 2011-03-09 11:42:00

+0

它不是來自xcode。它直接進入答案框。爲了這個代碼的工作 - 你不需要一個協議(除非你想幹淨的代碼沒有gcc警告)。 「失敗!」是什麼意思?不是所謂的方法?我會用自定義setter更新代碼。 – Eimantas 2011-03-09 11:55:37

+0

我得到這個:錯誤:期望說明符 - 限定符列表之前'returnedProperty' @property returnedProperty = _returnedProperty; – 2011-03-09 12:36:47

0

您可以使用它的情節串連圖板很容易。在SecondViewController實施使用此並創建VIewController.h屬性(第一種觀點的控制器)命名dataFromSecondView

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 
{ 
    NSString *textvalue = self.SecondViewText.text; 
    ViewController *destination = segue.destinationViewController; 
    destination.dataFromSecondView = textvalue; 
}