【问题标题】:Passing data between 2 UIViewController using delegate and protocol [duplicate]使用委托和协议在2个UIViewController之间传递数据[重复]
【发布时间】:2023-04-07 11:43:01
【问题描述】:

我知道这个问题已经在这里被问过很多次了。但我是第一次处理这件事,仍然无法在我的脑海中完美地实现它。这是我实现的将数据从SecondViewController 传递到FirstViewController 的委托方法的代码。

FirstViewController.h

#import "SecondViewController.h"

@interface FirstViewController : UITableViewController<sampleDelegate> 
@end

FirstViewController.m

@interface FirstViewController ()

// Array in which I want to store the data I get back from SecondViewController.
@property (nonatomic, copy) NSArray *sampleData;
@end

@implementation FirstViewController
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
   SecondViewController *controller = [[SecondViewController alloc] init];          
   [self.navigationController pushViewController:controller animated:YES];
}
@end

SecondViewController.h

@protocol sampleDelegate <NSObject>
- (NSArray*)sendDataBackToFirstController;
@end

@interface SecondViewController : UITableViewController
@property (nonatomic, strong) id <sampleDelegate> sampleDelegateObject;
@end

SecondViewController.m

@interface SecondViewController ()
@property (strong, nonatomic) NSArray *dataInSecondViewController;
@end

@implementation SecondViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.dataInSecondViewController = [NSArray arrayWithObjects:@"Object1", @"Object2", nil];
}

- (NSArray*)sendDataBackToFirstController
{
    return self.dataInSecondViewController;
}
@end

我做得对吗?我只希望它将self.dataInSecondViewController中的数据发送到FirstViewController并将其存储在NSArray属性sampleDataFirstViewController中。

不知何故,我无法在FirstViewController 中访问sendDataBackToFirstController。我还缺少什么其他东西来访问sendDataBackToFirstController 那里?

【问题讨论】:

  • 您需要将第一个vc设置为第二个vc的代理。所以第二个vc的委托方法需要在第一个vc中实现。然后在触发事件时从第二个 vc 调用该方法。从您的情况来看,如果您想要拥有数据源或委托,则不清楚。如果您使用第二个 vc 作为第一个 vc 的数据源,则它是第一个 vc 请求数据。但是您只想在第二个 vc 中发生某些事件时将值返回给第一个 vc,然后是它的委托类型。然后您需要将返回类型更改为 void 并将数据作为参数传递。
  • 正确。我尝试在我的 First vc 的 didSelectRow... 中执行 controller.delegate = self。但不知何故控制器无法找到委托对象。到目前为止,我的代码似乎正确吗?
  • 请关注@gdavis和art的回答
  • @NANNAV - 不知道这个问题是如何重复的。我确实在我的问题的最初开始提到它已经得到了回答,但这个问题是特定于我的实现的。那里的答案对我实现我的代码没有多大帮助,这就是我开始另一个问题的原因。
  • 除了协议和委托之外,还有一个选项是简单且易于实现的块......

标签: ios uiviewcontroller delegates protocols


【解决方案1】:

不太对。首先,您需要在第一个视图控制器中分配委托属性,以便第二个视图控制器知道要向哪个对象发送消息。

FirstViewController.m

controller.delegate = self;

其次,您可以向后发送和接收委托方法。您以 FirstViewController 预计在第二个控制器上调用 sendDataBackToFirstController 的方式设置它。在委托模式中,SecondViewController 是发送消息并可选择使用该方法发送数据的那个。所以,你应该把你的委托声明改成这样:

@protocol sampleDelegate <NSObject>
- (void)secondControllerFinishedWithItems:(NSArray* )newData;
@end

然后,当您的 SecondViewController 完成其任务并需要通知其委托时,它应该执行以下操作:

// ... do a bunch of tasks ...
// notify delegate
if ([self.delegate respondsToSelector:@selector(secondControllerFinishedWithItems:)]) {
    [self.delegate secondControllerFinishedWithItems:arrayOfNewData];
}

我在这里添加了一个额外的 if 语句,以确保委托在实际发送之前会响应我们想要发送的方法。如果我们的协议中有可选方法但没有这个,应用就会崩溃。

希望这会有所帮助!

【讨论】:

  • 您和@art 的解释对我理解协议和委托的整个流程有很大帮​​助。我按照你和艺术的代码来实现代表,我得到了我想要的。我将委托属性更改为弱而不是强以防止保留循环。
【解决方案2】:

请关注这里

FirstViewController.h

   #import "SecondViewController.h"

   @interface FirstViewController : UITableViewController<sampleDelegate> 
   @end

FirstViewController.m

  @interface FirstViewController ()

  // Array in which I want to store the data I get back from SecondViewController.
  @property (nonatomic, copy) NSArray *sampleData;
  @end

 @implementation FirstViewController
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
 {
   SecondViewController *controller = [[SecondViewController alloc] init]; 
   controller.sampleDelegateObject=self;      
  [self.navigationController pushViewController:controller animated:YES];

 }

  //implementation of delegate method
  - (NSArray*)sendDataBackToFirstController
{
  return self.dataInSecondViewController;
}
 @end

SecondViewController.h

 @protocol sampleDelegate <NSObject>
- (NSArray*)sendDataBackToFirstController;
@end

@interface SecondViewController : UITableViewController
@property (nonatomic, strong) id <sampleDelegate> sampleDelegateObject;
@end
SecondViewController.m

 @interface SecondViewController ()
 @property (strong, nonatomic) NSArray *dataInSecondViewController;
 @end

 @implementation SecondViewController

 - (void)viewDidLoad
{
  [super viewDidLoad];
  self.dataInSecondViewController = [NSArray arrayWithObjects:@"Object1", @"Object2", nil];
   //calling the delegate method
  [sampleDelegateObject sendDataBackToFirstController];
}


  @end

【讨论】:

  • 协议的实现会在你要实现的类中
  • 感谢您提供代码的详细信息。
【解决方案3】:

第一次更改 @property (nonatomic, strong) id &lt;sampleDelegate&gt; sampleDelegateObject;@property (nonatomic, weak) id &lt;sampleDelegate&gt; sampleDelegateObject; 防止保留循环搜索 google 用该词进行解释。

第二 你的协议应该是

@protocol sampleDelegate <NSObject>
- (void)sendDataBackToFirstController:(NSArray*)dataToSendBack;
@end

当你想发回数据时,你调用[self.sampleDelegateObject sendDataBackToFirstControoler:yourData];,第一个视图控制器必须在协议中实现这些方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-07
    • 2015-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-13
    相关资源
    最近更新 更多