[iOS Swift4]如何支持 ViewControllers(模态和推送)

Posted

技术标签:

【中文标题】[iOS Swift4]如何支持 ViewControllers(模态和推送)【英文标题】:[iOS Swift4]How to back ViewControllers (modal and push) 【发布时间】: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() 谢谢 【参考方案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")

【讨论】:

以上是关于[iOS Swift4]如何支持 ViewControllers(模态和推送)的主要内容,如果未能解决你的问题,请参考以下文章

如何实现 AutoFill Credential Provider Extensions - iOS 11, swift4

如何使用 Swift 4 在 iOS 9+ 中创建瀑布布局

如何在 iOS Swift4 中创建这个圆形?

iPad 上的 UIViewController 处理方向 iOS 6.0

用于 swift4 ios 的 Socket.io

iOS Swift4如何保护接口中定义的计算属性不被赋值?