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

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

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

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

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

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

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

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

提前致谢 马特

【问题讨论】:

    标签: objective-c ios delegates uinavigationcontroller


    【解决方案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
    

    【讨论】:

    • 非常感谢您的回复,为他人提供很好的参考。我还问了另一个与此类似的问题,然后给出了完整的答案。 stackoverflow.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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-12
      • 2019-10-08
      • 2011-06-26
      相关资源
      最近更新 更多