在视图控制器 ios 7 之间传递数据

Posted

技术标签:

【中文标题】在视图控制器 ios 7 之间传递数据【英文标题】:Passing data between view controllers ios 7 【发布时间】:2013-10-21 09:44:37 【问题描述】:

我正在开发一个应用程序,我需要在视图控制器之间传递数据。我知道这是一个常见问题,但我找不到我的问题的答案:我能够将数据从 FirstViewController(在我的情况下为 MasterViewController)传递到 SecondViewControllerSettingsViewController)但不是逆转。发生的情况是我从 SecondViewController.m 文件中的 FirstViewController 调用了一个方法。这有效,它记录数据。但是当我退出 SecondViewController(使用[[self presentingViewController] dismissViewControllerAnimated:YES completion:nil];)时,数据会被重置。 我尝试使用其他方法来传递数据,但没有奏效。我正在使用此代码来传递数据:

MasterViewController *vc = [[MasterViewController alloc] initWithNibName:@"MasterViewController" bundle:nil];

[vc setPorts:SelectedPorts];

我也尝试将[vc setPorts:SelectedPorts]; 替换为vc.selectedCellIndexes = SelectedPorts;,但出现了同样的问题。

setPorts 方法在 FirstViewController.h 文件中声明,SelectedPorts 是我在 SecondViewController.m 中声明的变量(我检查过它不是 nil)。

这是 FirstViewController.m 中的setPorts:

- (void) setPorts:(id)selectedPorts 
selectedCellIndexes = selectedPorts;
NSLog(@"selectedCellIndexes : %@", selectedCellIndexes);

这记录了良好的值,但是当我将其记录到 FirstViewController.m 中的 viewWillAppear 时,它会重置为我从 SecondViewController.m 调用该方法之前的值。

澄清一下,如果我不退出 SecondViewController.m,数据不会重置。

我确实阅读了您所有的 cmets,非常感谢您的帮助。为方便起见,我使用了一个全局变量。

感谢您的帮助。

【问题讨论】:

数据被重置为 secondViewController 并且它的 iVar 被释放。您需要在主视图控制器上创建一个 ivar,以一致地保存您正在谈论的数据。 你能给我一些建议吗? @jrock007 您如何向我们展示您是如何尝试声明和实现委托协议的? 怎么了@jrock007? 7人花时间写答案。可以让我们更新吗? 【参考方案1】: 您在MasterViewController 中有一个端口列表,并且您希望在SettingsViewController 中使用它。 MasterViewController 可以保存此列表,SettingsViewController 应该可以访问它。

SettingsViewController 中,有一个setSelectedPort 方法:

@property (nonatomic, retain) id selectedPorts

- (void) setPorts:(id)selectedPorts;

该方法将选定的端口列表保存到一个属性中。

MasterViewController 中,调用SettingsViewController 并提供列表。

SettingsViewController *vc = [[SettingsViewController alloc] initWithNibName:@"SettingsViewController" bundle:nil];
[vc setSelectedPorts:yourValue]; 

SettingsViewController内修改列表时,即使离开SettingsViewControllerMasterViewController中包含的端口列表也不会移动。

【讨论】:

问题是用户输入了端口,所以我不能只调用一个方法来改变它们 如果您将列表实例(引用)保存到SecondViewController 中,则不会。然后你可以在列表中做任何你想做的改变。只需将其保存为属性即可。答案已更新。【参考方案2】:

在 secondViewController 中,你创建协议

  #import <UIKit/UIKit.h>

@protocol sampleDelegate <NSObject>

- (void)passValue:(id)selectedPorts

@end

@interface SecondViewController : UIViewController

@property (nonatomic, strong) id <sampleDelegate> passDelegate;

@end

在 viewDidLoad 或任何你需要的方法中,调用这样的方法,

[self.passDelegate passValue:selectedPorts];

在 FirstViewController.h 中,

导入委托&lt;sampleDelegate&gt;

#import "SecondViewController.h"

@interface FirstViewController : UIViewController<SampleDelegate>

@end

在 FirstViewController.m 中,

-(void)passValue:(id)selectedPorts

    id receivedValues = selectedPorts;

并在您的 SecondViewController 分配中设置 self,

SecondViewController *vc = [[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil];
vc.passDelegate = self;

【讨论】:

在 FirstViewController.m 中分配它?我需要将数据从 SecondViewController 传递给 SecondViewController 顺便说一句,我忘了说我正在使用故事板 需要反转吗? secondview 到主视图? 是的,我需要将数据传回... FROM SecondViewController TO MasterViewController 你需要创建委托并通过委托方法传递数据【参考方案3】:

获取结果没有什么异常。通过做

MasterViewController *vc = [[MasterViewController alloc] initWithNibName:@"MasterViewController" bundle:nil];   
[vc setPorts:SelectedPorts];

您正在从您的SecondViewController 创建MasterViewController 的新实例。这与您导航到SecondViewController 的位置不同。所以你不会得到预期的结果。由于您将端口(@98​​7654325@)设置为新创建的主实例。

无需创建新实例,只需将MasterViewController 中的MasterViewController 引用保存在属性中并在移动到第二个VC 之前分配它。作为初学者,我建议这种方式。但是使用委托是传回数据的首选方式。

【讨论】:

【参考方案4】:

要么使用委托方法从模态 VC 与主 VC 通信,或者如果你想从模态 VC 检索一些被操纵的对象,你可以这样做。

将对象设置为模态视图控制器的 .h 文件中的属性(因此它们是公共的)。

在主 VC 中使用 unwind segues,只需这样做:

-(IBAction)exitModalVC:(UIStoryboardSegue*)segue

    SomeObject *obj = ((YourModalVC*)segue.sourceViewController).someObject;

    //Do what you want with obj

编辑:

这只有在你使用 unwind segue 时才有效(这是在使用故事板时消除模态 VC 的一种巧妙方法)

你正在使用这个,它不是展开的segues:

[[self presentingViewController] dismissViewControllerAnimated:YES completion:nil];

【讨论】:

【参考方案5】:

您正在从第二个视图控制器创建第一个视图控制器的新实例,而不是访问原始调用者的同一实例。这就是为什么当您返回原始调用者 - 您的 MasterViewController 时,您可以看到日志但数据不存在的原因。

您需要使用委托方法。检查我的答案SO.

【讨论】:

【参考方案6】:

这是与对象所有权相关的问题。 请按照以下步骤操作:

据了解,您希望将“SecondViewController”的值反转为“FirstViewController”

不要在 SecondViewController 中创建 FirstViewController 的新对象,它不会起作用。

    在“SecondViewController.h”文件中创建“FirstViewController”对象。 @property (nonatomic,strong) FirstViewController *firstViewController;

    当您从 FirstViewController 导航到 SecondViewController 时,请传递“self”。 例如SecondViewController *vc = [[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil]; vc.firstViewController = self;

    如果你想将反向值传递给 FirstViewController 然后在 SecondViewController.m 文件中。 [self.firstViewController setPorts:SelectedPorts];

    然后在 FirstViewController.m 中使用最新值刷新您的控件。

尝试上面的代码将完全按照您的要求工作。

【讨论】:

当我在 SecondViewController.h 中添加它时出现错误:@property (nonatomic,strong) MasterViewController *masterViewController;错误是:“未知类型名称 MasterViewController”和“具有“保留(或强)”属性的属性必须是对象类型。MasterViewController 是我的 FirstViewController 的名称 请在 SecondViewController 中导入相同的(MasterViewController)类。 #import "MasterViewController.h" 您创建了 MasterViewController 的对象,这就是您需要导入同一个类的原因。 #import "MasterViewController.h"

以上是关于在视图控制器 ios 7 之间传递数据的主要内容,如果未能解决你的问题,请参考以下文章

在视图控制器之间传递数据 - iOS Xcode - 啥是好方法?

如何在视图控制器之间传递数据而不在 ios 中使用 segue?

在视图控制器之间传递 iOS 10 Segue 中的数据 [重复]

在多个视图控制器之间传递数据[重复]

如何使用委托将数据从多个视图控制器传递回根视图控制器? IOS 7

Swift - 在视图控制器之间传递数据