【问题标题】:[iOS Swift4]How to back ViewControllers (modal and push)[iOS Swift4]如何支持 ViewControllers(模态和推送)
【发布时间】:2019-05-11 18:28:33
【问题描述】:

[观看次数]
Main.storyboard - ViewController
↓ 推
Second.storyboard - SecondViewController
↓ 模态
Third.storyboard - ThirdViewController

我一直在尝试从 ThirdViewController → SecondViewController → ViewController 回来

从 ThirdViewController 回到 SecondViewController 就可以了。

   // ThirdViewController
    @IBAction func tapBackBtn(_ sender: Any) {   
        self.dismiss(animated: true, completion: nil)
        SecondViewController().back()
    }

但是 func back() - self.navigationController?.popViewController(animated: true) 不起作用。

   // SecondViewController
    func back() {
    // Come here though...
     self.navigationController?.popViewController(animated: true)
    }

    @IBAction func tapBackBtn(_ sender: Any) {
        // It works though...
        self.navigationController?.popViewController(animated: true)
    }

有没有办法从 Third/SecondViewController 自动返回到 ViewController?
谢谢。

【问题讨论】:

  • 第一个问题是:为什么你对一个ViewController 使用不同的故事板?如果可能,则仅在一个情节提要中添加所有 ViewController。它将提供控制器之间的轻松导航:(1. Push to next, 2. Present controller from anywhere, 3. Back to one or back to more than one or back to root controller)
  • 大家好,谢谢大家。使用不同的故事板来计划项目。我终于在 SecondVC 上使用此代码解决了我的问题。 override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) if let presented = self.presentedViewController { if type(of: presented) == ThirdViewController.self { self.back() } } }谢谢

标签: ios swift


【解决方案1】:

它不起作用,因为通过SecondViewController().back(),您实际上调用了SecondViewController 的初始化程序并创建了视图控制器的新实例。此实例与您要隐藏的导航堆栈中的实例不同。因此,您在实际上不在导航堆栈且没有导航控制器的实例中调用返回函数。

要解决此问题,您可以在窗口层次结构中找到一个导航控制器,如下所示:

@IBAction func tapBackBtn(_ sender: Any) {   
    self.dismiss(animated: true) {
         guard navigationControlller = UIApplication.shared.windows.first?.rootViewController as? UINavigationController else { return }
         navigationController?.popViewController(animated: true)
    }
}

或者更好的解决方案是重新考虑您的应用架构,并将导航责任交给一些协调的视图控制器。所以协调器会知道ThirdViewController 何时应该消失并在需要时在NavigationController 调用popViewController

【讨论】:

    【解决方案2】:

    你想回到第一个视图控制器;又名 root

    self.navigationController?.popToRootViewController(animated: true)
    

    您还可以弹回特定的控制器:

    self.navigationController?.popToViewController(aController, animated: true)
    

    【讨论】:

      【解决方案3】:
        self.presentingViewController?.presentingViewController?.dismiss(animated: true, completion: nil)
      

      将此代码添加到第三个视图控制器中的 backButton,它将带您到第一个 ViewController

      【讨论】:

        【解决方案4】:

        首先,您不需要在 ThirdViewController 的 tapBackBtn 方法中执行 SecondViewController().back(),因为这段代码什么都不做。

        接下来,如果您在第一个 ViewController 中执行 push,则应该通过点击导航控制器中的后退按钮实现默认的 pop

        以下是如何简单地完成任务的示例:

        // FirstViewController

        @IBAction func showButtonDidPress(_ sender: Any) {
            let storyboard = UIStoryboard(name: "Second", bundle: nil)
            let secondViewController = storyboard.instantiateViewController(withIdentifier: "SecondViewController")
            navigationController?.pushViewController(secondViewController, animated: true)
        }
        

        // SecondViewController

        @IBAction func presentButtonDidPress(_ sender: Any) {
            let storyboard = UIStoryboard(name: "Third", bundle: nil)
            let thirdViewController = storyboard.instantiateViewController(withIdentifier: "ThirdViewController")
            present(thirdViewController, animated: true, completion: nil)
        }
        

        // 第三视图控制器

        @IBAction func dismissButtonDidPress(_ sender: Any) {
            dismiss(animated: true, completion: nil)
        }
        

        正如您在此处看到的,我不使用任何 segue,也使用单独的故事板。

        此外,您可以使用 UIStoryboard 的简单扩展来使您的代码更漂亮:

        extension UIStoryboard {
            static var main: UIStoryboard {
                return UIStoryboard(name: "Main", bundle: nil)
            }
        
            static var second: UIStoryboard {
                return UIStoryboard(name: "Second", bundle: nil)
            }
        
            static var third: UIStoryboard {
                return UIStoryboard(name: "Third", bundle: nil)
            }
        }
        

        因此,要创建 ViewController 的新实例,您将执行以下操作:

        let secondViewController = UIStoryboard.second.instantiateViewController(withIdentifier: "SecondViewController")
        

        【讨论】:

          猜你喜欢
          • 2018-11-14
          • 1970-01-01
          • 1970-01-01
          • 2015-09-17
          • 1970-01-01
          • 2015-02-10
          • 2018-05-06
          • 1970-01-01
          • 2012-08-09
          相关资源
          最近更新 更多