2011-03-09 47 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; 
}