如何关闭当前的 ViewController 并在 Swift 中更改为新的 ViewController?
Posted
技术标签:
【中文标题】如何关闭当前的 ViewController 并在 Swift 中更改为新的 ViewController?【英文标题】:How to dismiss the current ViewController and change to the new ViewController in Swift? 【发布时间】:2018-03-05 09:32:08 【问题描述】:我是 ios swift 的新手。我有三个 ViewController。 page-A 是根控制器,它将呈现给 page-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?
提前致谢。
【问题讨论】:
您之前是否从任何其他控制器展示控制器 A?或控制器是在应用加载时首次显示的根控制器 为什么要关闭当前的 ViewController? @iOSGeek 我的错。它有三个视图控制器,我有编辑。 为此使用协议, 检查工作输出我发布了一个答案 【参考方案1】:这是你可以尝试的工作代码
您的控制器已被解雇并倾向于制作一个新控制器
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)
输出
【讨论】:
【参考方案2】:尝试将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,而此时不存在。
因此,解决方案是您可以获得对正在呈现加载器的呈现视图控制器的引用,该控制器将在关闭加载器并从那里呈现新视图控制器后出现。
【讨论】:
我试过了,没有显示错误,也没有显示C-Viewcontroller。 如果 AViewController 是根视图控制器,那么看看这个答案:***.com/a/22654105/3882414 但是如果你有另一个视图控制器正在呈现 AViewController 那么上面的代码应该可以工作【参考方案3】:在你的 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
【讨论】:
【参考方案4】:您正在尝试使用视图控制器的引用(实例),该引用将不再存在于内存中。
试试这个
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")
【讨论】:
我试过了,没有显示错误,也没有显示C-Viewcontroller。 那是因为您当前的视图控制器仍然存在。一旦您关闭当前的视图控制器,就呈现它。一个视图控制器一次只能呈现一个视图控制器。延迟 1 秒后执行此操作。如果无法执行,请告诉我。我将与您分享完整的功能代码。 我延迟了1秒,但还是没有输入let presentingVC = self.presentingViewController
。以上是关于如何关闭当前的 ViewController 并在 Swift 中更改为新的 ViewController?的主要内容,如果未能解决你的问题,请参考以下文章
如何将第二个viewcontroller文本字段值传递给第一个viewcontroller数组并在swift4中点击按钮时关闭
Swift:关闭在当前上下文中显示图片的 ViewController 时不时冻结屏幕