访问另一个视图控制器

Posted

技术标签:

【中文标题】访问另一个视图控制器【英文标题】:Accessing another viewcontroller 【发布时间】:2013-01-12 15:28:30 【问题描述】:

我正在尝试从另一个视图控制器 (ios) 访问一些东西。

我有我的 ViewController.h:

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController <UITextFieldDelegate> 
    ...


@end

ViewController.m:

#import "ViewController.h"
#import "ViewController2.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad

   ViewController2.someVar = @"cakes"; // this is where I'm trying to set something in vc2

ViewController2.h:

#import <UIKit/UIKit.h>

@interface ViewController2 : UIViewController <UITableViewDataSource, UITableViewDelegate, UISearchDisplayDelegate>

   ...


@property (nonatomic, copy) NSString *someVar;

@end

ViewController2.m:

#import "ViewController2.h"

@interface ViewController2 ()

@end

@implementation ViewController2

@synthesize someVar;

etc.

但是在我尝试访问这个 var 的那一行,它给了我以下错误:

在“ViewController2”类型的对象上找不到属性“someVar”。

我将通过什么方式访问这个其他视图控制器?

【问题讨论】:

【参考方案1】:

您必须在您的Viewcontroller.m 中创建一个ViewControlle2 对象。

ViewController2 *myVC2 = [[ViewController2 alloc] initWithNibName:@"ViewController2" bundle:nil];
myVC2.someVar = @"cakes";

【讨论】:

好吧,有点工作。当我 NSLog 像 myVC2.var 一样的 VC1 中的 var 时,它会显示出来,这很棒。但是当我从 VC2 NSLog 时,它又是空的! @Cake,你在VC2哪里登录的? viewDidLoad。但我不明白为什么这很重要:/ @Cake:如果你在两个地方都登录,你看到它们的顺序是什么?您是在 nib 中、在代码中还是在两者中创建 ViewController2? 您必须记录“self.someVar”,而不仅仅是“someVar”。【参考方案2】:

另一种方法是使用委托。如果您在 AppDelegate 中创建了 ViewController1,您还应该在 AppDelegate 中创建 ViewController2,或者在您创建 ViewControllers 的任何位置。然后您 ViewController1 将向 AppDelegate 发送一条消息以从 ViewController2 获取数据,反之亦然。这使得 ViewController1 和 ViewController2 不再相互依赖。

所以在 AppDelegate.h 中我们会有这样的东西

@interface AppDelegate : NSObject <MyViewControllerDelegate>

@property (nonatomic) ViewController1 *viewController1;
@property (nonatomic) ViewController2 *viewController2;

@end

然后在两个视图控制器中,您可以在 .h 中添加这一行

@property (nonatomic) id<MyViewControllerDelegate> delegate;

这只是为我们提供了一个变量,用于从 ViewController 的 .m 中引用委托

你还需要创建 MyViewControllerDelegate 协议,所以在一个名为 MyViewControllerDelegate.h 的文件中

@protocol MyViewControllerDelegate

- (ViewController1 *) viewController1;

- (ViewControlelr2 *) viewController2;

@end

那么当你在 AppDelegate.m 中创建 ViewControllers 时,你还应该将 AppDelegate 设置为 ViewController 的委托。

self.viewController1 = [[ViewController1 alloc] init];
self.viewController1.delegate = self;
self.viewController2 = [[ViewController2 alloc] init];
self.viewController2.delegate = self;

因此,所有这些委托设置完成后,您应该能够通过委托从 viewController1 访问 viewController2.someVar,方法是:

self.delegate.viewController2.someVar = @"Cakes";

希望这不是太啰嗦。

【讨论】:

感谢这个谜。由于我还没有在 Cocoa 中达到高级水平,所以我确实有一些问题: - 这是解决它的更好方法吗,使用委托类来控制两个视图控制器? - 我不确定“委托”的定义,所以我查看了 Apple 的描述。这是其中的内容:“在垃圾收集环境中,接收者维护对其委托的强引用”***说:“弱引用是一种不保护被引用对象不被垃圾收集器收集的引用”。这不是两个相反的陈述吗?我迷路了:P 在这种情况下,我们使用委托作为数据源,这有点不同。在the apple developer page 的底部,他们谈到了一点。它还讨论了一般的代表,您可能会觉得这很有帮助。我通常最终会在 JAVA 等语言中使用类似于接口的方式,因此视图控制器将其一个更通用的函数的主体委托给它的委托,而不是自己定义它。 只要这是一个好的解决方案,我几乎总是以这种方式实现它,只是因为它将视图控制器与数据分开。因此,如果您删除了一个视图控制器或稍后在项目中彻底更改它,您不必完全更改信息的存储方式,它只存在于委托中,并且仍然可供其他控制器访问。跨度> 谢谢。关于您的解决方案, MyViewControllerDelegate.h 应该是什么样子?因为 - (ViewController1 *) viewController1;会给我一个错误“缺少方法声明的上下文”。 确保包含@protocol@end。我认为这应该会有所帮助。还要确保在协议顶部包含类的标头。

以上是关于访问另一个视图控制器的主要内容,如果未能解决你的问题,请参考以下文章

UIViewController 通过 xib 加载另一个视图控制器,尝试访问默认视图导致崩溃

从一个视图控制器访问 CLLocationManager 变量到另一个视图控制器

从另一个视图控制器访问变量。迅速

从另一个视图控制器访问常量

使用汉堡菜单时访问另一个视图控制器中的变量的问题

从一个视图控制器访问一组图像到另一个视图控制器,以添加滑动手势识别器