在发送者视图控制器被解雇后执行 segue

Posted

技术标签:

【中文标题】在发送者视图控制器被解雇后执行 segue【英文标题】:Performing segue after sender view controller is dismissed 【发布时间】:2017-04-20 18:18:20 【问题描述】:

基本上,我在滑出式菜单中有一个按钮(它是它自己的视图控制器,覆盖了Origin 屏幕的一部分,我们称它为Menu),按下该按钮时,将执行模态转换到另一个控制器,比如说Destination

有什么方法可以在按下Menu 中的按钮(转到Destination)后,将Menu 解散回Origin,然后转到Destination

这听起来很傻,但我认为我以前见过应用程序这样做。就我而言,想要这样做的原因是,一旦我在Destination 上按下“完成”,它就会将该控制器解散回Menu,而我希望它只是解散回Origin。我不能只从Destination 转回Origin

代码:

这就是我从Origin 打开Menu 的方式:

let interactor = Interactor()

@IBAction func openMenu(_ sender: AnyObject) 
    performSegue(withIdentifier: "openMenu", sender: nil)



@IBAction func edgePanGesture(sender: UIScreenEdgePanGestureRecognizer) 
    let translation = sender.translation(in: view)

    let progress = MenuHelper.calculateProgress(translationInView: translation, viewBounds: view.bounds, direction: .Right)

    MenuHelper.mapGestureStateToInteractor(
        gestureState: sender.state,
        progress: progress,
        interactor: interactor)
            self.performSegue(withIdentifier: "openMenu", sender: nil)
    


override func prepare(for segue: UIStoryboardSegue, sender: Any?) 
    if let destinationViewController = segue.destination as? MenuViewController 
        destinationViewController.transitioningDelegate = self
        destinationViewController.interactor = interactor
        destinationViewController.currentRoomID = self.currentRoomID
    

这是我的prepareForSegue,目前从MenuDestination,没什么特别的:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) 
    super.prepare(for: segue, sender: sender)

    let inviteVC = segue.destination as! InviteVipViewController
    inviteVC.currentRoomID = self.currentRoomID

最后解雇Destination 只是一个简单的

@IBAction func cancelButtonPressed(_ sender: Any) 
    self.dismiss(animated: true, completion: nil)

我看到了这个问题,这基本上就是我想要做的,但不幸的是没有答案:Performing segue after dismissing modal swift

抱歉,如果这听起来令人困惑,但如果有人知道我在说什么,并且可以让我知道如何设置 segues/prepareForSegues 以使其工作,任何输入将不胜感激!

【问题讨论】:

既然你已经在使用segue了,为什么不从Destination做一个unwind segue呢?在 Origin 中实现 didUnwind,它应该跳过菜单 这似乎是我需要的,我刚刚尝试过,但唯一的问题是它会在返回原始控制器之前暂时停止在菜单上。有什么办法可以解决吗? 【参考方案1】:

基于对this answer 的修改,以下应该可以工作:

在您的故事板中,删除通过点击菜单按钮触发的转场并转到目的地。

创建一个从 Origin 视图控制器到 Destination 视图控制器的新 segue。这个 segue 将手动执行。

当您在菜单中选择目的地选项时,让菜单自行关闭,然后在 Origin 上执行目的地转场,如下所示:

    // This code goes in Menu, and you should call it when
    //    the menu button is tapped.
    //
    // presentingViewController is Origin
    weak var pvc = self.presentingViewController

    self.dismiss(animated: true) 

        // Menu has been dismissed, but before it is destroyed
        //  it calls performSegue on Origin
        pvc?.performSegue(withIdentifier: "openDestination", sender: nil)
    

当 Destination 被关闭时,您应该会看到 Origin,而根本看不到 Menu。

我在一个示例应用程序中对此进行了测试,其中“菜单”不是滑出,而是一个完整的模式视图控制器,它对我有用。

编辑:在使用@KingTim 进行故障排除时,他发现我们需要将segue 从UINavigationController(而不是Origin)连接到Destination。这是因为 Origin 位于导航控制器内部。在发现之后,它奏效了。

【讨论】:

谢谢,这很有趣 - 我试过了,当我关闭 Destination 时,它回到了 Menu,而不是 Origin。更具体地说,我将您的代码完全添加(除了我的 segue 名称不同)到我的 IBAction 中,该 IBAction 处理被点击以呈现目的地的菜单按钮。 其实我看错了你的评论。您答案中的代码应该在 Origin 控制器中吗?如何在 Origin 上调用 Destination segue?我通常会在按下的菜单按钮的 IBAction 中调用 segue,这显然与菜单控制器挂钩。 @KingTim 我已更新我的答案以解决您的问题。请重新阅读整个答案。解决方案没有改变,但我添加了希望澄清事情的 cmets。告诉我。 感谢您的更新.. 我仍然遇到崩溃:*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Receiver (<SpontiStoryboard.ChatViewController: 0x7fb6b102fe00>) has no segue with identifier 'chatToInvite'' 我确实设置了 chatToInvite 从聊天(来源)到邀请(目的地),并将您建议的代码放在菜单中按下的邀请按钮的 IBAction 中。【参考方案2】:

如果您的呈现视图嵌入在导航控制器中,那么您可以这样做:

    weak var pvc:UIViewController! = self.presentingViewController?.childViewControllers[0]
    dismiss(animated: true)
    
        pvc.performSegue(withIdentifier: "SegueID", sender: nil)
    

【讨论】:

【参考方案3】:

presentingViewController 的简单解决方案

if let destinationVC = self.presentingViewController as? YourViewController 
    destinationVC.isBooleanPassed = true
    destinationVC.selectedString = "here comes your string"
    destinationVC.selectedInteger = 12345


dismiss(animated: true, completion: nil)

【讨论】:

以上是关于在发送者视图控制器被解雇后执行 segue的主要内容,如果未能解决你的问题,请参考以下文章

在 Xcode 中执行 segue 后如何关闭视图控制器?

如何在触发退出 segue 之前执行操作?

在alerview被解雇后如何使webview成为第一响应者

关闭模态视图控制器,然后执行 segue

执行 segue 后,文本字段永久位于标签中

Segue 不会执行 Swift