我是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?
提前致谢。
答案 0 :(得分: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)
}
}
}
输出
答案 1 :(得分: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")
}
}
}
答案 2 :(得分: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函数。
问题是你在被解散后(即从窗口层次结构中移除)尝试从加载器中呈现BViewController,此时该窗口不存在。
因此,解决方案是您可以获得对呈现视图控制器的引用,该控制器呈现加载器并且在解除加载器并从那里呈现新视图控制器之后将出现。
答案 3 :(得分:0)
在其完成处理程序
protocol BProtocol: class {
func didClose()
}
以上是一种方法,另一种方式是通过委托
视图控制器中的:
var delegate: BProtocol?
self.dismiss(animated: true) {
self.delegate?.didClose()
}
B视图控制器
为协议
添加委托方法extension AViewController: BProtocol {
func didClose() {
//present C
}
}
并且在B中解雇
public class HomeController : Controller
{
public ActionResult Index()
{
var api = NeoRPC.ForTestNet();
此委托将由A ViewController实现为
{{1}}