如何关闭当前的 ViewController 并更改为 Swift 中的新 ViewController?
How to dismiss the current ViewController and change to the new ViewController in Swift?
我是 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
我是不是漏了什么?
问题:
如何在 Swift 中关闭当前的 ViewController 并更改为新的 ViewController?
提前致谢。
您正在尝试使用视图控制器的引用(实例),它将不再存在于内存中。
试试这个
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 函数。
问题是您试图在被解雇后(即从 window 层次结构中删除)从加载程序中呈现 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 视图控制器中
为协议添加委托方法
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
}
}
这是您可以尝试的工作代码
您的控制器已被解雇并倾向于创建一个新控制器
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)
}
}
}
输出
我是 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
我是不是漏了什么?
问题: 如何在 Swift 中关闭当前的 ViewController 并更改为新的 ViewController?
提前致谢。
您正在尝试使用视图控制器的引用(实例),它将不再存在于内存中。
试试这个
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 函数。
问题是您试图在被解雇后(即从 window 层次结构中删除)从加载程序中呈现 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 视图控制器中
为协议添加委托方法
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
}
}
这是您可以尝试的工作代码
您的控制器已被解雇并倾向于创建一个新控制器
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)
}
}
}
输出