在 Swift 中呈现一个视图控制器,关闭它并呈现一个不同的视图控制器
Present a view controller, dismiss it and present a different one in Swift
我有一个根视图控制器,它有一个按钮,当用户按下它时,会出现另一个视图控制器。
第二个控制器有一个关闭选项,它只返回根视图控制器,还有一个按钮,当用户触摸它时,它会关闭当前视图控制器,因此它会返回根视图控制器一秒钟并显示另一个一.
转到我使用的第一个控制器:
let vc = FirstController()
self.present(vc, animated: true, completion: nil)
当在另一个视图控制器中时,我 select 只关闭我这样做的按钮。
self.dismiss(animated: true, completion: nil)
因此,对于需要关闭并呈现另一个控制器的第二个控制器,我尝试了以下操作:
self.dismiss(animated: true, completion: {
let vc = SecondController()
self.present(vc, animated: true, completion: nil)
})
但是我得到一个错误:
Warning: Attempt to present <UINavigationController: 0xa40c790> on <IIViewDeckController: 0xa843000> whose view is not in the window hierarchy!
发生错误是因为您在关闭 FirstController 后试图从 FirstController 显示 SecondController。这不起作用:
self.dismiss(animated: true, completion: {
let vc = SecondController()
// 'self' refers to FirstController, but you have just dismissed
// FirstController! It's no longer in the view hierarchy!
self.present(vc, animated: true, completion: nil)
})
这个问题和我昨天的一个问题非常相似。
针对您的情况进行了修改,我建议这样做:
weak var pvc = self.presentingViewController
self.dismiss(animated: true, completion: {
let vc = SecondController()
pvc?.present(vc, animated: true, completion: nil)
})
只有呈现的视图控制器(Root)可以关闭它呈现的视图控制器(First 或 Second)。
所以你需要在根视图控制器的 class 中调用 dismiss(animated:completion:)
,而不是在任何其他视图控制器中调用:
class RootViewController: UIViewController {
func buttonTapped() {
let vc = FirstViewController()
vc.delegate = self
present(vc, animated: true)
}
}
extension RootViewController: FirstViewControllerDelegate {
func firstDidComplete() {
dismiss(animated: true) {
let vc = SecondViewController()
vc.delegate = self
present(vc, animated: true)
}
}
}
extension RootViewController: SecondViewControllerDelegate {
func secondDidComplete() {
dismiss(animated: true) {
let vc = ThirdViewController()
present(vc, animated: true)
}
}
}
// and so on
如果 FirstViewController 呈现其他视图控制器并且您想要它的关闭动画,请按如下方式实现 FirstViewController:
extension FirstViewController: OtherViewControllerDelegate {
func otherDidComplete() {
dismiss(animated: true) {
self.delegate?.firstDidComplete()
}
}
}
我有一个根视图控制器,它有一个按钮,当用户按下它时,会出现另一个视图控制器。
第二个控制器有一个关闭选项,它只返回根视图控制器,还有一个按钮,当用户触摸它时,它会关闭当前视图控制器,因此它会返回根视图控制器一秒钟并显示另一个一.
转到我使用的第一个控制器:
let vc = FirstController()
self.present(vc, animated: true, completion: nil)
当在另一个视图控制器中时,我 select 只关闭我这样做的按钮。
self.dismiss(animated: true, completion: nil)
因此,对于需要关闭并呈现另一个控制器的第二个控制器,我尝试了以下操作:
self.dismiss(animated: true, completion: {
let vc = SecondController()
self.present(vc, animated: true, completion: nil)
})
但是我得到一个错误:
Warning: Attempt to present <UINavigationController: 0xa40c790> on <IIViewDeckController: 0xa843000> whose view is not in the window hierarchy!
发生错误是因为您在关闭 FirstController 后试图从 FirstController 显示 SecondController。这不起作用:
self.dismiss(animated: true, completion: {
let vc = SecondController()
// 'self' refers to FirstController, but you have just dismissed
// FirstController! It's no longer in the view hierarchy!
self.present(vc, animated: true, completion: nil)
})
这个问题和我昨天
针对您的情况进行了修改,我建议这样做:
weak var pvc = self.presentingViewController
self.dismiss(animated: true, completion: {
let vc = SecondController()
pvc?.present(vc, animated: true, completion: nil)
})
只有呈现的视图控制器(Root)可以关闭它呈现的视图控制器(First 或 Second)。
所以你需要在根视图控制器的 class 中调用 dismiss(animated:completion:)
,而不是在任何其他视图控制器中调用:
class RootViewController: UIViewController {
func buttonTapped() {
let vc = FirstViewController()
vc.delegate = self
present(vc, animated: true)
}
}
extension RootViewController: FirstViewControllerDelegate {
func firstDidComplete() {
dismiss(animated: true) {
let vc = SecondViewController()
vc.delegate = self
present(vc, animated: true)
}
}
}
extension RootViewController: SecondViewControllerDelegate {
func secondDidComplete() {
dismiss(animated: true) {
let vc = ThirdViewController()
present(vc, animated: true)
}
}
}
// and so on
如果 FirstViewController 呈现其他视图控制器并且您想要它的关闭动画,请按如下方式实现 FirstViewController:
extension FirstViewController: OtherViewControllerDelegate {
func otherDidComplete() {
dismiss(animated: true) {
self.delegate?.firstDidComplete()
}
}
}