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

发布于 2024-10-21 03:58:41 字数 474 浏览 1 评论 0原文

几天来我一直在努力在两个视图控制器之间传递数据,并且感到非常困惑。我是 Objective-C 的新手,发现有些部分很难让我理解。

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

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

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

我想做正确的事情并想在我的程序中使用选项 4 - 委托

问题是,我不理解委托以及如何设置和实现它们。

任何人都可以提供一个关于如何使用委托和 2 个视图控制器设置和传递 NSArray 的基本示例。

提前致谢 马特

I have been battling with passing data between two view controllers for a couple of days now and getting very confused. I'm new to Objective-C and finding some parts tricky to get my head round.

I have a Navigation Controller, FirstView is a form and on this form I have a button which loads SecondView which contains a TableView for the user to select some options. I then want to pass the selection back to the FirstView controller and display the data etc...

I have read alot about this (stackoverflow, iphonedevsdk, CS 193P Resources) and the options i've seen are,

1) ivar in app delegate (dirty and not recommended)
2) create a singleton
3) create a data model class
4) Use protocols and delegates (recommended by apple)

I want to do things right and want to use option 4 - Delegates in my program

Problem is, I don't understand delegates and how to setup and implement them.

Could anyone provide a basic example on how to setup and pass an NSArray using the delegate and 2 view controllers.

Thanks in advance
Matt

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

久伴你 2024-10-28 03:58:41

委派是在这种情况下使用的正确模式,但您的描述看起来不太像委派,因为它使用全局变量。也许您在应用程序委托中存储全局变量,您应该始终尽量避免这种情况。

以下是代码的大致轮廓:

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

Delegation is the correct pattern to be used in this case, but your description doesn't look much like delegation as it is using a global variable. Perhaps you're storing global variables in your App Delegate which you should always try to avoid.

Here's a rough outline of what the code should look like:

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
蘸点软妹酱 2024-10-28 03:58:41

从我的头顶上掉下来。您可以将 _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

Off top of my head. You can replace _returnedProperty with your custom object and in setReturnedProperty method do all the magic before actually assigning the checked value from the table.

@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
薄荷梦 2024-10-28 03:58:41

您可以使用故事板,这非常简单。在 SecondViewController 的实现中使用它,并在 VIewController.h(第一个视图的控制器)中创建一个名为 dataFromSecondView 的属性

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

You can use storyboard its quite easy. Use this in the implementation of SecondViewController and create a property in VIewController.h (The first view's controller) named dataFromSecondView

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
  NSString *textvalue = self.SecondViewText.text;
  ViewController *destination = segue.destinationViewController;
  destination.dataFromSecondView = textvalue;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文