使用委托将数据传回导航堆栈

Posted

技术标签:

【中文标题】使用委托将数据传回导航堆栈【英文标题】:Using a delegate to pass data back up the navigation stack 【发布时间】:2011-03-09 11:03:50 【问题描述】:

几天来,我一直在与在两个视图控制器之间传递数据作斗争,并且感到非常困惑。我是 Objective-C 的新手,发现有些地方很难搞清楚。

我有一个导航控制器,FirstView 是一个表单,在这个表单上我有一个加载 SecondView 的按钮,其中包含一个 TableView 供用户选择一些选项。然后我想将选择传递回 FirstView 控制器并显示数据等...

我已经阅读了很多关于此的内容(***、iphonedevsdk、CS 193P 资源),我看到的选项是,

1) 应用委托中的 ivar(脏,不推荐) 2)创建一个单例 3)创建数据模型类 4) 使用协议和委托(苹果推荐)

我想做正确的事并想在我的程序中使用选项 4 - 代表

问题是,我不了解代表以及如何设置和实施它们。

谁能提供一个基本示例,说明如何使用委托和 2 个视图控制器设置和传递 NSArray。

提前致谢 马特

【问题讨论】:

【参考方案1】:

委托是在这种情况下使用的正确模式,但您的描述看起来不像委托,因为它使用的是全局变量。也许你在你的 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.m

@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

【讨论】:

非常感谢您的回复,为他人提供很好的参考。我还问了另一个与此类似的问题,然后给出了完整的答案。 ***.com/questions/5210535/… 你能告诉我如何从第一个视图到第二个视图做同样的事情,比如从第一个视图到第二个视图发送字符串,特别设置为委托给自己..?在此先感谢:) 为什么在创建 id 委托和属性 委托时给出错误提示“现有实例变量”。?谢谢。【参考方案2】:

在我的脑海中。您可以将_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

【讨论】:

感谢 Elimantas,试图实现这一点但失败了!这是真正的协议和委托实现吗?我没有看到 @protocol 和 。你在xcode中有这个代码吗?还是你直接把这个写到答案框中? 它不是来自 xcode。它直接进入答案框。要使此代码正常工作 - 您不需要协议(除非您想要没有 gcc 警告的干净代码)。 “失败!”是什么意思?方法不是调用了吗?我将使用自定义设置器更新代码。 我得到这个:错误:预期的说明符限定符列表在此行的“returnedProperty”之前@property returnedProperty=_returnedProperty; 对不起 Eimantas,也许是我太简单了,但我无法让该代码正常工作。非常感谢您的帮助..【参考方案3】:

您可以很容易地使用故事板。在SecondViewController 的实现中使用它并在VIewController.h(第一个视图的控制器)中创建一个名为 dataFromSecondView 的属性

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender

  NSString *textvalue = self.SecondViewText.text;
  ViewController *destination = segue.destinationViewController;
  destination.dataFromSecondView = textvalue;

【讨论】:

以上是关于使用委托将数据传回导航堆栈的主要内容,如果未能解决你的问题,请参考以下文章

使用委托将数据传回上一个VC并更新自定义单元格

使用委托将 NSMutableArray 传回前一个视图控制器

反转Segue时如何将信息传回iOS?

使用 Delegates 通过多个 viewController 传回数据

将委托方法多级传递给 navigationController 堆栈

导航堆栈之前视图之间的协议委托