显示和关闭模态视图控制器


77

谁能给我示例代码,我可以使用该示例代码首先呈现一个模态视图控制器,然后将其关闭?这就是我一直在尝试的:

NSLog(@"%@", blue.modalViewController);
[blue presentModalViewController:red animated:YES];
NSLog(@"%@", blue.modalViewController);
[blue dismissModalViewControllerAnimated:YES];
NSLog(@"%@", blue.modalViewController);

这段代码在viewDidLoad中(“ blue”和“ red”都是UIViewController的子类)。我希望我将显示红色视图,然后立即将其隐藏起来,并带有一些动画。但是,这段代码仅呈现模态视图,而不会将其忽略。任何的想法?第一个日志显示“空”,而其他两个日志显示<RedViewController: 0x3d21bf0>

另一点是,如果将这段代码放在applicationDidFinishLaunching中:红色视图根本不会出现,并且所有日志都为“ null”


就像下面有人说的,presentModalViewController:animated:已被弃用。现在,您需要presentModalViewController:animated:completion:在完成模块中使用并执行以下操作(如果您想等到red出现该操作)。无论如何,请阅读@MatterGoal建议的文章:developer.apple.com/library/ios/#featuredarticles/…
Ferran Maylinch 2015年

Answers:


109

首先,将代码放在applicationDidFinishLaunching中时,可能是从Interface Builder实例化的控制器尚未链接到您的应用程序的情况(因此“ red”和“ blue”仍然是nil)。

但是要回答您的第一个问题,您做错了什么是调用dismissModalViewControllerAnimated:了错误的控制器!应该是这样的:

[blue presentModalViewController:red animated:YES];
[red dismissModalViewControllerAnimated:YES];

通常,“红色”控制器应决定在某个时候解散自己(可能是单击“取消”按钮时)。然后,“红色”控制器可以在上调用该方法self

[self dismissModalViewControllerAnimated:YES];

如果仍然无法正常运行,则可能与控制器以动画方式呈现有关,因此您可能不允许在呈现控制器后不久就将其关闭。


58
根据适用于iPhone OS的View Controller编程指南,这在关闭模式视图控制器时是不正确的,您应该使用委托。因此,在呈现模态视图之前,请先让自己成为委托,然后从模态视图控制器中调用该委托以将其关闭。
奥斯卡·戈麦斯

1
请记住,自io6以来,这种表示模式视图的方式已被弃用。使用:[self presentViewController:动画:完成:];相反
simon_smiley 2014年

5
@OscarGomez不,《 View Controller编程指南》没有说这种方法不正确。它确实说您建议的方法是“首选方法”。换句话说,虽然您的方法可能适用于许多情况,但这并不是设计使然,不是唯一的方法,只是您应该首先尝试的方法。 我建议您添加您引用的方法作为额外的答案,因为对于这样的问题有多个可行的答案,对于某些读者来说,您的答案可能更好。
Slipp D. Thompson 2014年

4
[self dismissModalViewControllerAnimated:YES];已弃用
交替

什么叫之间的区别dismissModalViewControllerAnimatedred还是blue?从文档看来,我们应该调用它blue(当前的VC)...
Ferran Maylinch 2015年

18

迅速

为Swift 3更新

在此处输入图片说明

故事板

创建两个每个都有一个按钮的View Controller。对于第二个视图控制器,将类名称设置为SecondViewController,情节提要ID设置为secondVC

ViewController.swift

import UIKit
class ViewController: UIViewController {

    @IBAction func presentButtonTapped(_ sender: UIButton) {
        
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let myModalViewController = storyboard.instantiateViewController(withIdentifier: "secondVC")
        myModalViewController.modalPresentationStyle = UIModalPresentationStyle.fullScreen
        myModalViewController.modalTransitionStyle = UIModalTransitionStyle.coverVertical
        self.present(myModalViewController, animated: true, completion: nil)
    }
}

SecondViewController.swift

import UIKit
class SecondViewController: UIViewController {
    
    @IBAction func dismissButtonTapped(_ sender: UIButton) {
        self.dismiss(animated: true, completion: nil)
    }
}

资源:


13

在xcode 4.52中,我最简单的方法是创建一个附加视图并使用segue modal将它们连接起来(控制将按钮从一个视图拖动到第二个视图,选择Modal)。然后将按钮拖动到您创建的第二个视图或模式视图。控制此按钮并将其拖动到头文件并使用动作连接。这将在controller.m文件中创建一个IBaction。在代码中找到您的按钮操作类型。

[self dismissViewControllerAnimated:YES completion:nil];

请注意,这将自动将消息转发至self.presentingViewController(根据UIViewController的文档),所以为了清楚起见,最好叫[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
HatchmasterĴ

9

presentModalViewController:

MainViewController *mainViewController=[[MainViewController alloc]init];
[self.navigationController presentModalViewController:mainViewController animated:YES];

dismissModalViewController:

[self dismissModalViewControllerAnimated:YES];

3

最简单的方法是使用Storyboard和Segue。

只需从TabBarController的FirstViewController(而非导航控制器)到使用登录UI的LoginViewController创建Segue,并将其命名为“ showLogin”。

创建一个返回BOOL的方法,以验证用户登录和/或他/她的会话是否有效……最好在AppDelegate上。称为isSessionValid。

在您的FirstViewController.m上,覆盖方法viewDidAppear,如下所示:

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    if([self isSessionValid]==NO){
        [self performSegueWithIdentifier:@"showLogin" sender:self];
    }
}

然后,如果用户成功登录,则只需关闭或弹出LoginViewController即可显示您的标签。

运作100%!

希望能帮助到你!


3

迅速

self.dismissViewControllerAnimated(true, completion: nil)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.