【问题标题】:Passing data between view controllers ios 7在视图控制器 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人花时间写答案。可以让我们更新吗?

标签: iphone ios objective-c uiviewcontroller ios7


【解决方案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 的新对象,它不会起作用。

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

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

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

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

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

        【讨论】:

        • 当我在 SecondViewController.h 中添加它时出现错误:@property (nonatomic,strong) MasterViewController *masterViewController;错误是:“未知类型名称 MasterViewController”和“具有“保留(或强)”属性的属性必须是对象类型。MasterViewController 是我的 FirstViewController 的名称
        • 请在 SecondViewController 中导入相同的(MasterViewController)类。 #import "MasterViewController.h"
        • 您创建了 MasterViewController 的对象,这就是您需要导入同一个类的原因。 #import "MasterViewController.h"
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-07-09
        • 2015-12-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多