presentViewController 和 pushViewController 之间的不同结果

Posted

技术标签:

【中文标题】presentViewController 和 pushViewController 之间的不同结果【英文标题】:Different Results Between presentViewController and pushViewController 【发布时间】:2013-07-14 06:31:39 【问题描述】:

对于在两次尝试以编程方式实例化和打开新视图之间看到的不同结果,我感到有些困惑。我有一个由 NSTimer 回调调用的方法(尽管我认为这不是那么相关),它尝试分配和初始化第二个视图控制器,并将其推送到堆栈上(我可能有我的命名法离开那里,对不起)。

查看 ViewController 编程指南和这里的一些答案,我确定了两个潜在的解决方案,它们都可以正常构建和运行,但我得到不同的结果,这两个都不能完全工作。

第一个使用presentViewController 方法。它看起来像这样:

SecondViewController *secondView = [[SecondViewController alloc] init];
[self presentViewController:secondView animated:YES completion:NULL];

...从某种意义上说,它确实有效。我在 SecondViewController 类的 viewDidLoad 方法中放置了一个 NSLog,它会打印出来。如果我还在那里以编程方式设置 UIColor,则屏幕颜色。但是,我在 Storyboard 中放置在此 VC 视图上的任何内容都不会显示 - 如果我不以编程方式为视图着色,则屏幕为黑色。

我尝试的第二种方法是因为我认为代码没有正确连接到我的 Storyboard(这是一种旧方法,仍然适用于 XIB 的 afaik)。它看起来像这样:

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard_iPhone" bundle:nil];
SecondViewController *secondView = (SecondViewController *)
[storyboard instantiateViewControllerWithIdentifier:@"secondView"];
[self.navigationController pushViewController:secondView animated:YES];

...但 viewDidLoad 和界面似乎都没有响应/被调用。

我还查看了 prepareForSegue 方法,但我不确定它是否会有所作为,因为我很确定我缺少一些东西......

我应该注意到我已经在 Identity Inspector 下设置了 ViewController 的 Storyboard ID。

如果有人能解释我的问题的直接解决方案和/或我遇到的问题的更大解释,那将不胜感激。

~杰西

【问题讨论】:

【参考方案1】:

使用presentViewController的第一个解决方案/问题,创建和演示都很好,但根本不涉及故事板。如果您在代码中创建视图内容(如颜色),或者如果 init 方法加载了 NIB 或其他内容,那么一切都会很好。

第二种方法看起来应该可以,所以可能是情节提要的名称错误,标识符的名称错误,或者navigationController为nil。

prepareForSegue 方法只会在 segue 由用户交互触发(其中 segue 在故事板中配置)或专门从代码触发的 segue 时调用。

通常,您希望主要使用一种形式来创建视图转换。如果您使用的是故事板,那么通常是在故事板中配置的 segues 并链接到 UI 项。然后,您将在“源”视图控制器中实现prepareForSegue,以传递“目标”视图控制器所需的任何附加信息。你应该通过this guide工作。

【讨论】:

感谢 cmets Wain。我理解您对 1 表单的看法,但在这种情况下,我试图从 NSTimer 回调加载/调用新的 ViewController,因此无法通过 UI 执行此操作,但我想继续使用 Storyboard对于我的应用程序的其余部分...我想我真的需要有关如何链接它们的建议,如果需要以及何时需要... 您关于 navigationController 的评论是 nil 只是为我触发了它——我没有将第一个 ViewController 嵌入到 Navigation Controller 中——这样做会使我的第二个 VC 正确显示! ...但是,我实际上并不希望将这些屏幕链接到 NavController 中-我正在尝试使这更像是导航到主菜单页面的超时启动页面,并且不希望能够去回到启动页面... 从拥有计时器的视图控制器中定义一个命名的segue,并从代码中触发它(performSegueWithIdentifier:sender:)。 我不完全确定这意味着什么。我是以编程方式还是从情节提要定义segue?如何让它拥有 NSTimer?等等。 转场在故事板中定义(参见指南中的“以编程方式触发转场”)。 'Own' 仅表示在触发时处理计时器操作方法的视图控制器。【参考方案2】:

因此,多亏了 Wain 的回答和 cmets,我得以正确地以编程方式实例化位于我的 Storyboard 中的新 UIViewController。在使用自定义Identifier 对第二个UIViewController 进行模态(见评论)后,我只需要在我的NSTimer 的回调方法中调用performSegueWithIdentifier 方法。似乎我的代码太多了,并且过度思考需要从我的第一个中以编程方式制作我的第二个UIViewController。这是我的代码的相关部分:

- (void)viewDidLoad 
    [super viewDidLoad];

    if(self.timer == nil) 
        self.timer = [NSTimer scheduledTimerWithTimeInterval:2.5 target:self selector:@selector(switchView) userInfo:nil repeats:NO];
    



- (void) switchView 
    [self performSegueWithIdentifier:@"timerDone" sender:self];

    [timer invalidate];
    self.timer = nil;       

【讨论】:

以上是关于presentViewController 和 pushViewController 之间的不同结果的主要内容,如果未能解决你的问题,请参考以下文章

presentViewController pushViewController和presentModalViewController

presentViewController pushViewController和presentModalViewController

IIViewDeckController 和 presentViewController

如何在封面视图和主页中使用“presentViewController”

presentViewController 和 UIViewController 布局

pushViewController和presentViewController的区别