[英]Dismiss or remove previous modally presented view controller as soon as the next one appear modally
我的目标包括很多视图需要根据每个用户操作以模态方式呈现不同的视图。 这就是我想要做的更清晰的视图层次结构和更好的用户体验。
- Root View Controller以模态方式呈现First View Controller
- 当我单击第一视图控制器上的按钮时,第二视图控制器以模态方式显示在它上面。
- 第二个视图控制器出现后,我想从视图层次结构中解除或删除第一个视图控制器。
我能这样做吗? 如果是这样 ,我该怎么办?
如果没有 ,解决这个问题的正确方法是什么,我将在每个视图上呈现许多模态呈现的视图控制器。 我想即使我想要忽略当前的观点,前一个观点仍然会在当前观点被忽略时出现。
更新:
VC1(Root)> VC 2(模态存在)> VC 3( 在VC 2上以模态存在)
当我关闭VC3
, VC2
仍然在视图内存上。 因此,我不想在我解除VC3
立即出现VC2
,而是希望通过从视图层次结构中删除或解除VC2
来查看VC1
。
想要 :在图像中,当我解雇蓝色时,我不希望在我的视图记忆中看到粉红色,我想在蓝色出现时立即将其删除。
这就是我想要做的。
任何帮助?谢谢。
所以,我们假设你有一个类似于的故事板:
应该发生的是:
在第三个ViewController按钮的动作中:
@IBAction func tapped(_ sender: Any) {
presentingViewController?.presentingViewController?.dismiss(animated: true, completion: nil)
}
正如你所看到的,通过访问presentingViewController当前视图控制器,你可以关闭该视图控制器以前的层次结构:
提供此视图控制器的视图控制器。
通过实现presentingViewController?.presentingViewController?
这意味着:呈现当前的ViewController :)
这看起来有点混乱,但很简单。
所以输出应该是这样的(我为viewControllers添加了背景颜色-as vc1:orange,vc2:black和vc3:light orange-以使其显得清晰):
编辑:
如果要求在中间删除ViewController(在本例中为第二个ViewController),则dismiss(animated:completion :)会自动执行此操作:
如果连续呈现多个视图控制器,从而构建一堆呈现的视图控制器,则在堆栈中较低的视图控制器上调用此方法会解除其直接子视图控制器以及堆栈上该子视图上方的所有视图控制器。 发生这种情况时,只有最顶层的视图以动画方式被删除; 任何中间视图控制器都可以从堆栈中删除。 最顶层的视图使用其模态过渡样式被忽略,这可能与堆栈中较低的其他视图控制器使用的样式不同。
参考你在问什么:
我想即使我想要忽略当前的观点,前一个观点仍然会在当前观点被忽略时出现。
我认为在UI上显而易见(我发现它没问题),但正如在dismiss
文档讨论中所提到的,第三个和第二个都将从堆栈中删除。 那是正确的方法。
你想要的是一个“放松segue”:
https://developer.apple.com/library/archive/technotes/tn2298/_index.html
它允许您同时关闭多个视图控制器,而无需知道堆栈中有多少个。
在VC1中,您将实现一个名为(例如) unwindToRoot
的IBAction
。 然后在VC3的故事板中,将“完成”按钮连接到“ Exit
对象,然后选择unwindToRoot
操作。
按下该按钮后,系统将关闭所需的所有视图控制器,以便将您带回VC1。
这比调用presentingViewController?.presentingViewController?.dismiss()
更好,因为VC3不需要知道它下面的视图控制器层次结构。
以下是我对不同角度的看法,
- Root View Controller提供第二视图控制器
- 将FirstView添加到第二个视图
- 按下按钮时关闭FirstView控制器。
第二视图控制器,
class ViewController: UIViewController, FirstViewControllerProtocol {
weak var firstViewController: FirstViewController?
override func viewDidLoad() {
super.viewDidLoad()
print("Not initiated: \(firstViewController)")
firstViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "FirstViewController") as? FirstViewController
addChildViewController(firstVC!)
firstViewController?.delegate = self
view.addSubview((firstViewController?.view)!)
print("Initiated: \(firstViewController)")
}
func dismiss() {
firstViewController?.view.removeFromSuperview()
firstViewController?.removeFromParentViewController()
}
}
FirstViewController,
protocol FirstViewControllerProtocol {
// Use protocol/delegate to communicate within two view controllers
func dismiss()
}
class FirstViewController: UIViewController {
var delegate: FirstViewControllerProtocol?
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func dismiss(_ sender: Any) {
delegate?.dismiss()
}
deinit {
print("BYE")
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.