如何解决关闭View Controller并以相同方法展示一个新控制器-Swift
问题摘要
-
我有两个视图控制器(VC1 = MainViewController和VC2 = ResultViewController)。 在VC1中,有一个名为endGame()的方法。在这种方法中,我既要关闭VC1,又要关闭VC2。
-
当我尝试先关闭VC1然后显示VC2时,VC1无法显示VC2,因为VC1已被关闭并且在堆栈中不存在。
dismiss(animated: true) { self.present(rvc,animated: true,completion: nil) }
-
当我尝试先展示VC2,然后关闭VC1时,VC2会显示1秒钟,然后立即消失。
present(rvc,animated: true) { self.dismiss(animated: true,completion: nil) }
我尝试过的事情
我也遇到了类似的问题:
- Dismissing a View Controller and displaying another View Controller。这是最接近我的问题的答案。建议使用协议。因此,通过使用协议,我解决了一半的问题->在VC2中,我既可以关闭VC2,也可以退出VC1。但是在VC1中,我不能同时关闭VC1,也不能同时退出VC2。
我使用最新的swift和Xcode版本。
我的代码
VC1
// protocol for presenting View Controllers
protocol VcDelegate: AnyObject {
func presentVc(vc: UIViewController)
}
// The main view controller of the game.
class MainViewController: UIViewController,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout,UICollectionViewDelegate,UIGestureRecognizerDelegate,VcDelegate {
// MARK: - Protocol functions & properties
func presentVc(vc: UIViewController) {
present(vc,animated: false,completion: nil)
}
// instance of VcDelegate protocol
weak var mvcDelegate: VcDelegate?
// MARK: - Properties
// the level of the game
var level: Int = 0
// the player's score
var score: Int = 0
/// Terminate the game for the next level and show results page
private func gameOver() {
// present the resultViewController
if let rvc = storyboard?.instantiateViewController(withIdentifier: "ResultViewController") as? ResultViewController {
rvc.resultLevel = level
rvc.resultscore = score
rvc.rvcDelegate = self
// dismiss MainViewController
dismiss(animated: true) {
// present ResultViewController by using instance of VcDelegate protocol
self.mvcDelegate?.presentVc(vc: rvc)
}
}
}
}
VC2
// This page is viewed after a level is finished. It shows level results and play again button.
class ResultViewController: UIViewController,completion: nil)
}
weak var rvcDelegate: VcDelegate?
// MARK: - Properties
// variable showing game level
var resultLevel = 0
// variable showing current score
var resultscore = 0
/// When play again button is tapped a new game starts (a new mainViewController is presented)
@IBAction func playAgainButton(_ sender: UIButton) {
// present a new MainViewController
if let mvc = storyboard?.instantiateViewController(withIdentifier: "MainViewController") as? MainViewController {
mvc.level = resultLevel
mvc.score = resultscore
mvc.mvcDelegate = self
// dismiss ResultViewController
dismiss(animated: true) {
// present MainViewController by using instance of VcDelegate protocol
self.rvcDelegate?.presentVc(vc: mvc)
}
}
}
}
解决方法
问题是,当您创建VC1
并以self
的形式传递mvcDelegate
时,实际上是通过了VC2
,而该VC2
即将被解散,并且在解散后{ {1}}无法显示任何视图控制器。
您可能需要先将一个视图控制器的委托传递给另一个视图控制器:
// Pass your delegate to the other view controller delegate
mvc.mvcDelegate = rvcDelegate
// dismiss ResultViewController
dismiss(animated: true) {
// present MainViewController by using instance of VcDelegate protocol
self.rvcDelegate?.presentVc(vc: mvc)
}
反之亦然:
// Pass your delegate to the other view controller delegate
rvc.rvcDelegate = mvcDelegate
// dismiss MainViewController
dismiss(animated: true) {
// present ResultViewController by using instance of VcDelegate protocol
self.mvcDelegate?.presentVc(vc: rvc)
}
如注释中所述,VC1是应用程序窗口的rootViewController
。因此,要实现您想要的目标,您需要替换rootViewController
。
在MainViewController中:
// Change rootViewController of the view's window with ResultViewController
view.window?.rootViewController = rvc
与ResultViewController中的相同:
// Change rootViewController of the view's window with MainViewController
view.window?.rootViewController = mvc
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。