使用 Swift 呈现新的 Viewcontroller 后如何关闭以前的 Viewcontroller?

Posted

技术标签:

【中文标题】使用 Swift 呈现新的 Viewcontroller 后如何关闭以前的 Viewcontroller?【英文标题】:How to dismiss previous Viewcontroller after presenting new Viewcontroller using Swift? 【发布时间】:2019-05-15 06:29:40 【问题描述】:

我的场景,在我的项目中,我维护了三个 ViewController (Main, VC1 and VC2)。在主要ViewController 我维护UIButton,此按钮单击VC1 呈现模型视图控制器。同样,VC1 我正在维护UIButton 并单击以将模型呈现给VC2。在VC2 展示后,我需要关闭 VC1。

//  presenting ViewController
var presentingViewController: UIViewController! = self.presentingViewController

self.dismissViewControllerAnimated(false) 
      // go back to MainMenuView as the eyes of the user
      presentingViewController.dismissViewControllerAnimated(false, completion: nil)

【问题讨论】:

你用什么样的segue来呈现VC1?您尝试实现的目标可能会打破导航预期。 @idmean 来自主 viewcontroller 按钮操作 我正在通过使用 let storyboard = UIStoryboard(name: "Main", bundle: nil) let controller: PreViewController = storyboard.instantiateViewController(withIdentifier :“预览控制器”)为! PreViewController let navController = UINavigationController(rootViewController: controller) self.present(navController, animated: true, completion: nil) @jackios 你是如何从 VC1 展示 VC2 的?? 试试这个***.com/questions/49234141/… 你愿意推动控制器而不是展示它吗? 【参考方案1】:

VC2 的关闭按钮操作中试试这个

var vc = self.navigationController?.presentingViewController
while vc?.presentingViewController != nil 
    vc = vc?.presentingViewController

vc?.dismiss(animated: true, completion: nil)

【讨论】:

嗨@RajeshKumar....谢谢你,我会尽力让你知道。顺便说一句,我可以把这条线放在哪里? 兄弟我在哪里可以放置这条线@RajeshKumar @jackios 你有什么按钮可以从 VC2 回到 Main 吗? 是的@RajeshKumarR 我正在维护VC2 中的关闭按钮。如果我把你的代码没有工作兄弟 @jackios 试试 self.navigationController?.presentingViewController?.presentingViewController?.dismiss(animated: true, completion: nil)【参考方案2】:

希望这会奏效:

您需要有一个 UIViewController 作为基础,在这种情况下,MainViewController 是基础 ViewController。您需要使用协议来调用 Controller 之间的导航。

你可以使用协议:-

在您的 FirstViewController 设置协议中:

protocol FirstViewControllerProtocol 
    func dismissViewController()


class FirstViewController: UIViewController 

    var delegate:FirstViewControllerProtocol!

    override func viewDidLoad() 
        super.viewDidLoad()

        

    override func didReceiveMemoryWarning() 
        super.didReceiveMemoryWarning()
    


    @IBAction func goBack(sender: AnyObject) 
        self.dismissViewControllerAnimated(true)  
            self.delegate!.dismissViewController()
        
    

现在在您的 MainViewController 中

class MainViewController: UIViewController, FirstViewControllerProtocol 

override func viewDidLoad() 
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.


override func didReceiveMemoryWarning() 
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.



@IBAction func goToFirstViewController(sender: AnyObject) 
    let viewController = self.storyboard?.instantiateViewControllerWithIdentifier(String(FirstViewController)) as! FirstViewController
    viewController.delegate = self
    self.presentViewController(viewController, animated: true, completion: nil)




//MARK: Protocol for dismiss
func dismissViewController() 
    if let viewController = self.storyboard?.instantiateViewControllerWithIdentifier(String(SecondViewController))
        self.presentViewController(viewController, animated: true, completion: nil)
    

【讨论】:

对不起。我不能得到你。 VC1 和 VC2 我都在维护当前模型。两个 VC 根都是 Main ViewController。 @Bhavisha Kharti 这不起作用在 VC2 中创建协议并在您的 VC1 中调用按钮单击它会关闭 VC2 但委托将在主 VC 中调用因此它将显示 VC 3 @wings 主视图控制器来展示 VC1,并从 VC1 到展示 VC2,带有导航栏和展示模型(从下到上过渡)我正在使用。在这里,VC1 到 VC2 呈现时间 VC1 不能关闭。如果我关闭 VC2,我可以再次看到 VC1。如何解决? 编辑了我的答案。请检查 @BhavishaKhatri。我想你没有理解我的问题。展示 VC2 后,我需要关闭 VC1。另外,我正在维护主视图控制器。 Main to Present model VC1 和 VC1 to present model VC2.如果我关闭 VC2,我可以看到 VC1,因为在 VC2 出现后我需要关闭 VC1。【参考方案3】:

要解决问题陈述,您可以使用Main 而不是VC1 呈现VC2

我们可以使用

VC1 中获得对Main 的引用
self.presentingViewController

当出现VC2 时,在present(_:animated:completion:) 方法的completionHandler 中关闭VC1

class Main: UIViewController 
    @IBAction func onTapButton(_ sender: UIButton) 
        let vc1 = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "VC1")
        self.present(vc1, animated: true, completion: nil)
    


class VC1: UIViewController 
    @IBAction func onTapButton(_ sender: UIButton) 
        let vc2 = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "VC2")
        vc2.view.backgroundColor = .blue
        self.dismiss(animated: false, completion: nil)
        self.presentingViewController?.present(vc2, animated: true, completion: nil)
    


class VC2: UIViewController 


这种方法给出了预期的输出。让我以防万一还需要什么。

【讨论】:

正是我想要的。【参考方案4】:

您需要从 mainVC 打开 vc2 - 为此,您需要一个委托方法,它会告诉 mainVC 关闭当前打开的 vc(即 vc1)并在成功块中打开 vc2。

代码片段:-

解雇(动画:假) //打开vc2 礼物(vc2)

【讨论】:

【参考方案5】:

在这种情况下,您需要从显示其他视图控制器的视图控制器(在您的情况下为 Main)调用解除。

正如您在上面的问题中所说的那样,主要呈现 VC1 和 VC1 然后呈现 VC2: 然后调用 Main.dismiss(animated: true, completion: nil) 将同时关闭 VC1 和 VC2。

如果您没有对根控制器(主)的引用,您可以链接几个 presentingViewController 属性来访问它;在最顶层的控制器(VC2)中是这样的:

presentingViewController?.presentingViewController?.dismiss(animated: true)

我希望这会有所帮助。

【讨论】:

【参考方案6】:

有一个present(_:animated:completion:) 方法可以完成。在里面你可以dismiss你的VC1。

您的代码将如下所示

@IBAction func ButtonTapped(_ sender: Any) 
    present(VC2, animated: true) 
        dismiss(animated: true, completion: nil)
    

【讨论】:

以上是关于使用 Swift 呈现新的 Viewcontroller 后如何关闭以前的 Viewcontroller?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Swift 3 'self.present' 呈现一个新的视图控制器

使用 Swift 呈现新的 Viewcontroller 后如何关闭以前的 Viewcontroller?

在关闭以前的 AlertViewController 后呈现新的 AlertViewController - Swift

iOS Swift - 在呈现新的视图控制器时呈现视图控制器向下滑动

在呈现新视图控制器后关闭当前视图控制器 - swift

Swift添加可点击的tableview