[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