在视图控制器 ios 7 之间传递数据
Posted
技术标签:
【中文标题】在视图控制器 ios 7 之间传递数据【英文标题】:Passing data between view controllers ios 7 【发布时间】:2013-10-21 09:44:37 【问题描述】:我正在开发一个应用程序,我需要在视图控制器之间传递数据。我知道这是一个常见问题,但我找不到我的问题的答案:我能够将数据从 FirstViewController(在我的情况下为 MasterViewController
)传递到 SecondViewController
(SettingsViewController
)但不是逆转。发生的情况是我从 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
内修改列表时,即使离开SettingsViewController
,MasterViewController
中包含的端口列表也不会移动。
【讨论】:
问题是用户输入了端口,所以我不能只调用一个方法来改变它们 如果您将列表实例(引用)保存到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 中,
导入委托<sampleDelegate>
,
#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
的位置不同。所以你不会得到预期的结果。由于您将端口(@987654325@)设置为新创建的主实例。
无需创建新实例,只需将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 中的数据 [重复]