从目标视图控制器推送新的视图控制器(swift)

Posted

技术标签:

【中文标题】从目标视图控制器推送新的视图控制器(swift)【英文标题】:Push new View Controller from destination View Controller (swift) 【发布时间】:2015-08-13 01:16:49 【问题描述】:

我正在尝试获取目标视图控制器来推送新的视图控制器,但我似乎无法以编程方式或通过故事板 segues 获得它。

这是我想要做的:

我有 3 个视图控制器(我们称它们为 A、B 和 C)。这三个都是在故事板中创建(设计的?)。我从视图控制器 A 开始,当用户按下按钮时,我想以模态方式呈现视图控制器 B,然后当用户在视图控制器 B 中选择一个单元格时,我希望视图控制器 B 被关闭(模态),并且我希望视图控制器 A 推送一个新的视图控制器(视图控制器 C)。

到目前为止,我尝试实现的方式是当用户按下视图控制器 A 中的按钮时,我以编程方式以模态方式推送视图控制器 B,然后当用户在视图控制器 B 中选择一个单元格时,我会返回查看控制器 A,并尝试从视图控制器 B 的 prepareForSegue 函数推送视图控制器 C,如下所示:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) 
    if let viewA = segue.destinationViewController as? ViewControllerA 
        let cell = sender as! ViewControllerBTableViewCell

        var viewC = storyboard?.instantiateViewControllerWithIdentifier("viewControllerC") as! ViewControllerC
        viewC.IDToDisplay = cell.userID
        viewA.navigationController?.pushViewController(viewC, animated: true)
        self.dismissViewControllerAnimated(true, completion: nil)
    

但是,当我运行这个...视图控制器 C 永远不会被推送!

我需要从视图控制器 A 推送视图控制器 C 的原因是我需要用户能够使用“后退”按钮从视图控制器 C 导航回视图控制器 A...而不是返回视图控制器B 来自视图控制器 C。

基本上我正在尝试创建的流程是视图 A -> 模态视图 B -> 视图 C ---> 回到视图 A,就好像视图 B 消失了(因为它应该消失)。 请注意,但是,在视图 A 推送到视图 C 之前,视图 B 确实需要能够设置视图 C 的 IDToDisplay 值。

是否有一种干净(标准)的方式来实现这一点?或者我将不得不变得笨拙?

【问题讨论】:

【参考方案1】:

你可以通过两种方式解决这个问题

第一个选项:您可以在 B 控制器中创建一个 clousure var 并在关闭 B 控制器之前执行它

例如:在 BController 中

class BTableViewController: UITableViewController 
     var pushClosure:(()->())?


    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) 

      pushClosure?()
      self.navigationController?.dismissViewControllerAnimated(true, completion: nil)      
    


并且在 prepareForSegue 的 A 控制器中做类似的事情

   override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) 
    if segue.identifier == "SegueID" 

        let nextView:BController = segue.destinationViewController as! BController
         nextView.pushClosure = 
            self.performSegueWithIdentifier("SegueID To C Controller", sender:nil)   
        
     
   

第二个选项是实现你自己的委托 在 BController 中

protocol ClassNameDelegate

 func pushToC()



class ClassName: NSObject 

  var delegate:ClassNameDelegate?



    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) 

      self.delegate.pushToC()
      self.navigationController?.dismissViewControllerAnimated(true, completion: nil)      
    
 

在控制器中

 class AViewController:ClassNameDelegate 

  func pushToC()
     self.performSegueWithIdentifier("SegueID To C Controller", sender:nil) 
  

  override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) 
       if segue.identifier == "SegueID" 
           let bController:BController = segue.destinationController as! BController
           bController.setDelegate = self
        
   

希望对你有帮助。

【讨论】:

感谢回复!委托选项似乎是标准方法......唯一的问题是,当我实现它时,当我从控制器 B 调用委托函数时,视图控制器 B 被解除,但没有任何反应。当我在控制器 A 的委托函数中编写打印语句时,它永远不会被打印。在视图控制器 B 中调用委托函数是否有任何原因不会触发? 弄清楚了,该函数没有在视图控制器 A 中触发,因为视图控制器 A 从未设置为视图控制器 B 的委托(哎呀,不知道我必须这样做)。当我实例化视图控制器 B 并呈现它时,将视图控制器 A 设置为视图控制器 B 的委托解决了问题。 很高兴它解决了您的问题,如果解决了问题,您可以查看答案。【参考方案2】:

用户是否在 viewController C 中按下按钮? 如果是这样,你可以使用这个:

self.navigationController?.popToRootViewControllerAnimated(true)

只需将它添加到您在 viewController C 中按下按钮的位置,它应该会返回到 A

【讨论】:

谢谢,但这并不能真正解决我的问题:用户在 viewController C 中做什么并不重要,我希望他们能够通过按“导航栏上的“返回”按钮。

以上是关于从目标视图控制器推送新的视图控制器(swift)的主要内容,如果未能解决你的问题,请参考以下文章

允许按钮在页面视图控制器中触发新的视图控制器 - swift

谷歌登录后使用 Swift 4 推送视图控制器

如何在swift中基于Json id从集合视图didSelectItemAt推送不同的视图控制器

是否可以使用情节提要从 swift 类中调用 Objective c 视图控制器类?

如何从主视图控制器在详细视图控制器中推送新视图?

如何在没有 Storyboard 的情况下推送新视图 Swift