在不调用每个 viewDidAppear 的情况下解雇 rootViewController

Posted

技术标签:

【中文标题】在不调用每个 viewDidAppear 的情况下解雇 rootViewController【英文标题】:Dismissing to rootViewController without calling each viewDidAppear 【发布时间】:2019-11-20 18:16:34 【问题描述】:

我的视图控制器就像 MainView -> NavigationController A -> ViewController A -> ViewController B -> ViewController C,我想关闭 ViewControllers(A、B 和 C)并再次显示 MainView...我使用了这条线

 self.view.window?.rootViewController?.dismiss(animated: false, completion: nil)

它工作得很好..问题是在解除 viewControllers(A、B 和 C)时,它会调用每个 viewDidAppear,这会运行我不想运行的代码.. 解除并执行的最佳做法是什么返回MainView而不调用每个viewController

【问题讨论】:

@Sammy 1- 我不使用情节提要 2- 我将每个视图呈现为全屏视图 这是我转到 ViewController A 的代码 let vc = ViewControllerA() let navigationController = UINavigationController(rootViewController: vc) navigationController.modalPresentationStyle = .fullScreen senderVC.present(navigationController, animated: true, completion: nil) 【参考方案1】:

您必须有其他导致问题的代码。

这是一个完整的例子......

PresDisViewController 是起始视图控制器 它的按钮创建一个以ViewControllerA为根的导航控制器 ViewControllerA 有一个按下 ViewControllerB 的按钮 ViewControllerB 有一个按钮可以按下 ViewControllerC ViewControllerC 有一个按钮可以执行你的 self.view.window?.rootViewController?.dismiss(animated: false, completion: nil)

每个 VC 都实现 viewDidAppear() 并将自己打印到调试控制台。

运行时的输出:

viewDidAppear scratchy.PresDisViewController
viewDidAppear scratchy.ViewControllerA
viewDidAppear scratchy.ViewControllerB
viewDidAppear scratchy.ViewControllerC
viewDidAppear scratchy.PresDisViewController

如您所见,当导航控制器被解除时,viewDidAppear 不会在 VC 中调用。

import UIKit

class ViewControllerA: UIViewController 

    let btn: UIButton = 
        let v = UIButton()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.setTitle("Do Push", for: .normal)
        v.backgroundColor = .red
        return v
    ()

    override func viewDidLoad() 
        super.viewDidLoad()

        view.backgroundColor = .white

        view.addSubview(btn)

        NSLayoutConstraint.activate([
            btn.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: -40.0),
            btn.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 0.0),
        ])

        btn.addTarget(self, action: #selector(didTap(_:)), for: .touchUpInside)

    

    @objc func didTap(_ sender: Any?) -> Void 
        let vc = ViewControllerB()
        self.navigationController?.pushViewController(vc, animated: true)
    

    override func viewDidAppear(_ animated: Bool) 
        super.viewDidAppear(animated)
        print("viewDidAppear", NSStringFromClass(self.classForCoder))
    



class ViewControllerB: UIViewController 

    let btn: UIButton = 
        let v = UIButton()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.setTitle("Do Push", for: .normal)
        v.backgroundColor = .systemYellow
        return v
    ()

    override func viewDidLoad() 
        super.viewDidLoad()

        view.backgroundColor = .white

        view.addSubview(btn)

        NSLayoutConstraint.activate([
            btn.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: 0.0),
            btn.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 0.0),
        ])

        btn.addTarget(self, action: #selector(didTap(_:)), for: .touchUpInside)

    

    @objc func didTap(_ sender: Any?) -> Void 
        let vc = ViewControllerC()
        self.navigationController?.pushViewController(vc, animated: true)
    

    override func viewDidAppear(_ animated: Bool) 
        super.viewDidAppear(animated)
        print("viewDidAppear", NSStringFromClass(self.classForCoder))
    



class ViewControllerC: UIViewController 

    let btn: UIButton = 
        let v = UIButton()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.setTitle("Do Dismiss", for: .normal)
        v.backgroundColor = .blue
        return v
    ()

    override func viewDidLoad() 
        super.viewDidLoad()

        view.backgroundColor = .white

        view.addSubview(btn)

        NSLayoutConstraint.activate([
            btn.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: 40.0),
            btn.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 0.0),
        ])

        btn.addTarget(self, action: #selector(didTap(_:)), for: .touchUpInside)

    

    @objc func didTap(_ sender: Any?) -> Void 
        self.view.window?.rootViewController?.dismiss(animated: false, completion: nil)
    

    override func viewDidAppear(_ animated: Bool) 
        super.viewDidAppear(animated)
        print("viewDidAppear", NSStringFromClass(self.classForCoder))
    




class PresDisViewController: UIViewController 

    let btn: UIButton = 
        let v = UIButton()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.setTitle("Do Present", for: .normal)
        v.backgroundColor = .orange
        return v
    ()

    override func viewDidLoad() 
        super.viewDidLoad()

        view.backgroundColor = .white

        view.addSubview(btn)

        NSLayoutConstraint.activate([
            btn.topAnchor.constraint(equalTo: view.topAnchor, constant: 60.0),
            btn.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 0.0),
        ])

        btn.addTarget(self, action: #selector(didTap(_:)), for: .touchUpInside)

    

    @objc func didTap(_ sender: Any?) -> Void 
        let vcA = ViewControllerA()
        let navVC = UINavigationController(rootViewController: vcA)
        navVC.modalPresentationStyle = .fullScreen
        present(navVC, animated: true, completion: nil)
    

    override func viewDidAppear(_ animated: Bool) 
        super.viewDidAppear(animated)
        print("viewDidAppear", NSStringFromClass(self.classForCoder))
    


【讨论】:

【参考方案2】:

这是通过 Storyboard 完成的。我不知道如何通过代码来做到这一点。我希望它有帮助 在你的 MainViewController 添加这个:

@IBAction func unwindToMainView(segue:UIStoryboardSegue)  

在所有其他ViewController(viewController A,ViewController B,ViewController C)中, 像这样单击并拖动

然后选择你在mainVC中添加的segue

现在选择那个segue并给它一个标识符

从这里你可以在任何你想要的地方使用该标识符执行 segue。我使用按钮来执行那个segue

【讨论】:

以上是关于在不调用每个 viewDidAppear 的情况下解雇 rootViewController的主要内容,如果未能解决你的问题,请参考以下文章

viewDidAppear 只在某些情况下被调用?

如何在不为每个帖子调用评论对象的情况下从墙上的帖子中获取评论计数?

如何在不使用表单的情况下从 jsp 调用 servlet

如何在不向下转换的情况下调用派生类的成员函数

在不使用 alpha 的情况下使用 UISegmentedControl 在视图 ios 之间切换?

算法回溯:如何在不存储状态的情况下进行递归