[英]How to dismiss the current ViewController and change to the new ViewController in Swift?
I am new to iOS swift. 我是iOS Swift的新手。 I have three ViewController.
我有三个ViewController。 The page-A is root controller and it will present to the page-B.
页面A是根控制器,它将呈现给页面B。 It has a timer in page-B.
在页面B中有一个计时器。 After 5 sec, it will change View from page-B to page-C , and close the page-B at the same time.
5秒钟后,它将视图从页面B更改为页面C,并同时关闭页面B。
In the ViewControll-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)
}
}
After timer execute for 5 sec , the BViewController
will dismiss itself and present to the BViewController
. 计时器执行5秒钟后,
BViewController
将关闭自身并呈现给BViewController
。
But the following error will happened: 但是会发生以下错误:
whose view is not in the window hierarchy
Did I missing something? 我错过了什么吗?
Question: How to dismiss the current ViewController and change to the new ViewController in Swift? 问题: 如何在Swift中关闭当前的ViewController并更改为新的ViewController?
Thanks in advance. 提前致谢。
Here is the Working code that you can Try 这是您可以尝试的工作代码
Your Controller which is Dismissed and Tend to make a new controller being presented 您的控制器被解雇并倾向于制作一个新的控制器
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)
}
}
}
Output 输出量
You are trying use a reference (instance) of view controller, that would no longer exist in memory. 您正在尝试使用视图控制器的引用(实例),该引用将不再存在于内存中。
Try this 尝试这个
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)
}
Note: Present a new view controller (filterVC) once your current view controller is dismissed. 注意:关闭当前视图控制器后,请提供一个新的视图控制器(filterVC)。 A view controller can present only a one view controller at time (if you choose present modally).
一个视图控制器一次只能显示一个视图控制器(如果您选择模态显示)。 Perform this operation after a delay of 1 second..
延迟1秒后执行此操作。
Try with this edited code. 尝试使用此编辑后的代码。
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")
}
}
}
Try changing dismissLoader function to something like: 尝试将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)
}
}
}
and remove the viewWillDisappear function. 并删除viewWillDisappear函数。
The problem is that you are trying to present the BViewController from the loader after being dismissed (ie removed from window hierarchy) which at that point doesn't exist. 问题是您正在尝试将BViewController从被解雇(即从窗口层次结构中删除)之后的加载器中呈现出来,那时该视图不存在。
So, the solution is that you could get a reference to the presenting view controller which is presenting the loader and which will appear after dismissing the loader and present the new view controller from there. 因此,解决方案是您可以获得对呈现视图控制器的引用,该视图控制器正在呈现加载器,并且在解除加载器并从此处呈现新视图控制器后将出现该视图控制器。
in your B view controller after its dismissed, in its completion handler 在您的B视图控制器被解雇后,在其完成处理程序中
self.dismiss(animated: true) {
if let presentingVC = self.presentingViewController {
present c view controller here
}
}
this above is one way to do so, another way is, through delegate 以上是这样做的一种方法,另一种方法是通过委托
in A view controller: 在视图控制器中:
if let bVC = self.storyboard.instantiateViewController(withIdentifier: B.controllerIdentifier) as? B {
bVC.delegate = self
self.present(bVC, animated: true, completion: nil)
}
inside B View Controller 内部B View Controller
add delegate method for Protocol 为协议添加委托方法
protocol BProtocol: class {
func didClose()
}
and in B dismiss 并在B中解雇
var delegate: BProtocol?
self.dismiss(animated: true) {
self.delegate?.didClose()
}
this delegate will be implemented by A ViewController as 此委托将由ViewController实现为
extension AViewController: BProtocol {
func didClose() {
//present C
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.