簡體   English   中英

如何在Swift中關閉當前的ViewController並更改為新的ViewController?

[英]How to dismiss the current ViewController and change to the new ViewController in Swift?

我是iOS Swift的新手。 我有三個ViewController。 頁面A是根控制器,它將呈現給頁面B。 在頁面B中有一個計時器。 5秒鍾后,它將視圖從頁面B更改為頁面C,並同時關閉頁面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

我錯過了什么嗎?

問題: 如何在Swift中關閉當前的ViewController並更改為新的ViewController?

提前致謝。

這是您可以嘗試的工作代碼

您的控制器被解雇並傾向於制作一個新的控制器

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)
        }
    }
}

輸出量

在此處輸入圖片說明

您正在嘗試使用視圖控制器的引用(實例),該引用將不再存在於內存中。

嘗試這個

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")
      }
    }

}

嘗試將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函數。

問題是您正在嘗試將BViewController從被解雇(即從窗口層次結構中刪除)之后的加載器中呈現出來,那時該視圖不存在。

因此,解決方案是您可以獲得對呈現視圖控制器的引用,該視圖控制器正在呈現加載器,並且在解除加載器並從此處呈現新視圖控制器后將出現該視圖控制器。

在您的B視圖控制器被解雇后,在其完成處理程序中

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

以上是這樣做的一種方法,另一種方法是通過委托

在視圖控制器中:

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

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

內部B View Controller

為協議添加委托方法

protocol BProtocol: class {
    func didClose()
}

並在B中解雇

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

此委托將由ViewController實現為

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM