考虑以下场景:我有一个基于故事板的应用程序。我将一个ViewController对象添加到情节提要中,将此ViewController的类文件添加到项目中,并在IB身份检查器中指定新类的名称。现在我该如何从AppDelegate中以编程方式引用这个ViewController呢?我已经使用相关的类创建了一个变量,并将其转换为IBOutlet属性,但我看不到任何方法能够在代码中引用新的ViewController -任何按住Ctrl键拖动连接的尝试都不起作用。
也就是说,在AppDelegate中,我可以像这样访问基本ViewController
(MyViewController*) self.window.rootViewController
但是,故事板中包含的任何其他ViewController呢?
发布于 2011-11-19 01:50:37
看看-[UIStoryboard instantiateViewControllerWithIdentifier:]
的documentation。这允许您使用在IB Attributes Inspector中设置的标识符从情节提要实例化视图控制器:
编辑后添加示例代码:
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"MainStoryboard"
bundle: nil];
MyViewController *controller = (MyViewController*)[mainStoryboard
instantiateViewControllerWithIdentifier: @"<Controller ID>"];
发布于 2016-02-04 19:47:56
通常,系统应该使用故事板来处理视图控制器实例化。您想要的是通过获取对self.window.rootViewController
的引用来遍历viewController层次结构,而不是初始化视图控制器,如果您正确设置了故事板,则视图控制器应该已经正确初始化。
所以,假设你的rootViewController
是一个UINavigationController,然后你想要发送一些东西到它的顶层视图控制器,你可以在你的AppDelegate的didFinishLaunchingWithOptions
中这样做
UINavigationController *nav = (UINavigationController *) self.window.rootViewController;
MyViewController *myVC = (MyViewController *)nav.topViewController;
myVC.data = self.data;
在Swift中,if非常类似:
let nav = self.window.rootViewController as! UINavigationController;
let myVC = nav.topViewController as! MyViewController
myVc.data = self.data
你真的不应该使用应用程序委托中的storyboard id来初始化视图控制器,除非你想绕过加载storyboard的正常方式,自己加载整个storyboard。如果你必须从AppDelegate初始化场景,你很可能做错了什么。我的意思是,想象一下,由于某些原因,你想要将数据发送到堆栈下面的视图控制器,AppDelegate不应该到达视图控制器堆栈来设置数据。这不关它的事。它的业务是rootViewController。让rootViewController处理它自己的子进程吧!因此,如果我通过在info.plist文件中删除对rootViewController的引用来绕过系统的正常情节提要加载过程,我最多只能使用instantiateViewControllerWithIdentifier:
实例化它,如果它是一个容器,则可能是它的根目录,比如UINavigationController。您要避免的是实例化已经由故事板实例化的视图控制器。这是一个我经常看到的问题。简而言之,我不同意公认的答案。这是不正确的,除非海报意味着要从info.plist中删除序列图像板的加载,否则您将加载2个序列图像板,这没有任何意义。这可能不是内存泄漏,因为系统初始化了根场景并将其分配给窗口,但随后您再次实例化它并再次分配它。你的应用程序一开始就很糟糕!
发布于 2019-08-18 21:01:58
UIStoryboard * storyboard = [UIStoryboard storyboardWithName:@"Tutorial" bundle:nil];
self.window.rootViewController = [storyboard instantiateInitialViewController];
https://stackoverflow.com/questions/8186375
复制相似问题