如何以编程方式转换到其他视图控制器?

时间:2014-10-29 01:19:09

标签: ios objective-c uiviewcontroller

嘿伙计我正在尝试让我的应用程序在调用某个方法时加载新视图。在方法内部,我有代码:

 ViewController *GameOverViewController = [[ViewController alloc] init];
 [self presentViewController:GameOverViewController animated:YES completion:nil];

直接来自How to switch views programmatically in a ViewController? (XCode iPhone)

无论如何,当我尝试从名为Game的视图控制器切换到名为 GameOverViewController 的视图控制器时,我只会遇到大量错误。主要是

"Unknown receiver 'ViewController'; did you mean 'UIViewController'

我的应用程序崩溃了。我显然做错了什么,但我不知道究竟是什么。我是否必须在我的Game.h或我的appDelegate中声明 GameOverViewController

编辑:如果重要的话,两个视图控制器都在相同的 main.Storyboard 文件中

2 个答案:

答案 0 :(得分:3)

未知接收者消息意味着它无法找到名为ViewController的视图控制器类的类定义。这真的是你用于“游戏结束”视图控制器的类的名称吗?如果是这样,您是否在#import "ViewController.h"文件的开头处完成了.m

根本问题是它无法找到名为ViewController的类。


除此之外,我们通常不再使用allocinit来实例化新的视图控制器,因为这个答案可能暗示了。这是一种与NIB一起使用的技术(仅当NIB名称与类名匹配时才有效)。

对于新开发者,我可能会鼓励您从故事板开始。任何现代教程都应该指导您如何使用故事板。 (谷歌“iOS故事板教程”,你可能会得到很多点击。)

例如,如果您的故事板上有一个“故事板标识符”为GameOverViewController的场景,那么您可以通过编程方式对其进行实例化,并将其显示为:

UIViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:@"GameOverViewController"];
[self presentViewController:controller animated:YES completion:nil];

或者,如果你的故事板有从当前场景到下一个场景的segue,你可以确保segue有自己的故事板标识符,例如GameOverSegue,然后你就这样执行:

[self performSegueWithIdentifier:@"GameOverSegue" sender:self];

但是在故事板上找到一个很好的介绍/教程,因为Stack Overflow的答案不会是一个非常富有成效的练习。


出于历史目的,值得注意的是,如果您使用的是NIB,则可以使用您在问题中引用的构造(但您必须确保(a)类名是正确的;并且(b你做了#import那个类标题)。如果目的地NIB的名称与班级不同,则必须执行以下操作:

UIViewController *controller = [[NSBundle mainBundle] loadNibNamed:@"nibname" owner:self options:nil]`;
[self presentViewController:controller animated:YES completion:nil];

但除非你使用NIB,否则这都是学术性的。如果使用故事板,如果需要以编程方式转换到新场景,请使用上述模式之一。

答案 1 :(得分:0)

你在头脑中。你应该放慢脚步,做更多的学习,否则事情会在整个地方崩溃。我建议你阅读一本关于iOS开发和练习的好书。

关于你的问题:

在您发布的代码中,您使用的是“ViewController”类。没有系统定义的类“ViewController”,虽然它是示例项目中的常见类名,我认为Xcode中的一些项目模板甚至可以创建具有该类名的根视图控制器。

您为变量指定的名称(上面代码中的“GameOverViewController”)是本地的,并不重要。那只是一个变量名。如果你愿意的话,你可以将它重命名为lateDinner,只要你在定义它的范围内的任何地方改变它,它就不会有任何区别。

您被告知“ViewController”类未知的事实表明它尚未在您的程序中的任何位置定义。

您需要一个定义ViewController类的@interface和@implementation部分。通常这些文件将分别位于名为ViewController.h和ViewController.m的文件中。他们可能看起来像这样:

//ViewController.h

#import <UIKit/UIKit.h>

@interface ViewController: UIViewController //Defines it as a subclass of UIViewController

// properties and methods of ViewController defined here

@end

.m文件:

//ViewController.m


@implementation ViewController

// Implementation of ViewController methods go here.

@end

也可以在单个头文件中包含多个类的接口,并在单个.m文件中包含多个类的实现,尽管我非常不喜欢这种做法。保持简单 - 每个.h / .m文件对一个类,文件名与类名相同。