如何解除当前的ViewController并更改为Swift中的新ViewController?

问题描述 投票:0回答:4

我是iOS swift的新手。我有三个ViewController。页面-A是根控制器,它将呈现给页面-B。它在页面B中有一个计时器。 5秒后,它将View从page-B更改为page-C,并同时关闭page-B。

ViewControll-B

class AViewController: UIViewController {

    var timer: Timer?

    override func viewDidLoad() {
        super.viewDidLoad()

        //set the timer , and chagne view to C ViewController
        Timer.scheduledTimer(timeInterval: 5,
                             target: self,
                             selector: #selector(self.changeToAnswerView),
                             userInfo: nil,
                             repeats: false)
    }


    @objc func changeToAnswerView() {
        dismissLoader()
    }

    func dismissLoader() {
        dismiss(animated: true) {
            print("Dismissing Loader view Controller")
        }
    }

    override func viewWillDisappear(_ animated: Bool) {
        //change view to Answer ViewController
        let filterVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "CViewControllerID")
        filterVC.modalPresentationStyle = UIModalPresentationStyle.custom
        self.present(filterVC, animated: true, completion: nil)
    }

}

在计时器执行5秒后,BViewController将自行解散并呈现给BViewController

但是会发生以下错误:

whose view is not in the window hierarchy

我错过了什么吗?

问题:如何解除当前的ViewController并更改为Swift中的新ViewController?

提前致谢。

ios swift viewcontroller
4个回答
2
投票

这是您可以尝试的工作代码

您的控制器被解雇并倾向于出示新的控制器

import UIKit

class pdfVC: UIViewController
{

    var timer : Timer?

    override func viewDidLoad()
    {
        super.viewDidLoad()
        timer = Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(pdfVC.timerAction), userInfo: nil, repeats: false)
    }

    @objc func timerAction()
    {
        if timer != nil {
            timer?.invalidate()
            dismiss(animated: true, completion: {
                print("Dismissed")
            })
        }
    }

    override func viewWillDisappear(_ animated: Bool) {
        if self.isBeingDismissed {
            let filterVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "demoViewController")
            filterVC.modalPresentationStyle = UIModalPresentationStyle.custom
            print("called")
            self.presentingViewController?.present(filterVC, animated: true, completion: nil)
        }
    }
}

产量

enter image description here


0
投票

尝试将dismissLoader函数更改为:

func dismissLoader() {
    dismiss(animated: true) {
        print("Dismissing Loader view Controller")
        if let presentingController = self.presentingViewController {
            let filterVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "BViewControllerID")
            filterVC.modalPresentationStyle = UIModalPresentationStyle.custom
            presentingController.present(filterVC, animated: true, completion: nil)
        }
    }
}

并删除viewWillDisappear函数。

问题是你正在尝试在被解散后(即从窗口层次结构中删除)从加载器中呈现一个ViewController,此时该控件不存在。

因此,解决方案是您可以获得对呈现视图控制器的引用,该呈现视图控制器呈现加载器并且在解除加载器并从那里呈现新视图控制器之后将出现。


0
投票

在你的B视图控制器被解雇后,在其完成处理程序中

 self.dismiss(animated: true) {
     if let presentingVC = self.presentingViewController {
        present c view controller here
     }
 }

以上是一种方法,另一种方式是通过委托

在A视图控制器中:

if let bVC = self.storyboard.instantiateViewController(withIdentifier: B.controllerIdentifier) as? B  {

        bVC.delegate = self
        self.present(bVC, animated: true, completion: nil)
    }

在B视图控制器内

为Protocol添加委托方法

protocol BProtocol: class {
    func didClose()
}

在B解雇

 var delegate:  BProtocol?
self.dismiss(animated: true) {
     self.delegate?.didClose()
 }

这个委托将由A ViewController实现为

extension AViewController: BProtocol {
    func didClose() {
        //present C
    }
}

0
投票

您正在尝试使用视图控制器的引用(实例),它将不再存在于内存中。

试试这个

if let presentingVC = self.presentingViewController {
        let filterVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "CViewControllerID")
        filterVC.modalPresentationStyle = UIModalPresentationStyle.custom
        presentingVC.present(filterVC, animated: true, completion: nil)
}

注意:取消当前视图控制器后,显示新的视图控制器(filterVC)。视图控制器一次只能显示一个视图控制器(如果您选择以模态方式存在)。延迟1秒后执行此操作..

编辑

尝试使用此编辑的代码。

Class AViewController: UIViewController {

    var timer: Timer?
    var presentingVC: UIViewController?
    override func viewDidLoad() {
        super.viewDidLoad()

        //set the timer , and chagne view to C ViewController
        Timer.scheduledTimer(timeInterval: 5,
                             target: self,
                             selector: #selector(self.changeToAnswerView),
                             userInfo: nil,
                             repeats: false)
    }


    @objc func changeToAnswerView() {
        dismissLoader()
    }

    func dismissLoader() {
        dismiss(animated: true) {
            print("Dismissing Loader view Controller")
        }
    }

    override func viewDidAppear(_ animated: Bool) {
         super.viewDidAppear(animated)
        //change view to Answer ViewController
        if let presentingVC = self.presentingViewController {
           self.presentingVC = presentingVC
        }
    }

    override func viewWillDisappear(_ animated: Bool) {
        //change view to Answer ViewController
        super.viewWillDisappear(animated)
       if let presentingVC = self.presentingVC {

        let filterVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "CViewControllerID")
        filterVC.modalPresentationStyle = UIModalPresentationStyle.custom
        presentingVC?.present(filterVC, animated: true, completion: nil)

      } else {
         print("Presenting View controller is nil")
      }
    }

}
© www.soinside.com 2019 - 2024. All rights reserved.