访问另一个视图控制器
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 加载另一个视图控制器,尝试访问默认视图导致崩溃