当发送视图控制器被解除后执行segue

9

基本上,我在一个滑出菜单中有一个按钮(它是自己的视图控制器,覆盖了部分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)
}

我看到了这个问题,基本上就是我正在尝试做的事情,但不幸的是没有答案:在dismiss modal swift后执行segue

如果有人知道我在说什么,并且可以告诉我如何设置segues/prepareForSegue使其工作,任何意见都将不胜感激!


既然您已经在使用过度动画了,为什么不从目标控制器执行 unwind 过渡呢?在原始控制器中实现 didUnwind 方法,就可以跳过菜单了。 - GetSwifty
这似乎是我需要的,我刚试了一下,唯一的问题是它在菜单上短暂停留后才返回原始控制器。有没有什么办法可以避免这种情况? - KingTim
3个回答

17

基于对这个答案的修改,以下方法应该可以实现:

在你的Storyboard中,删除通过点击菜单按钮并前往目标界面的那个segue。

创建一个新segue,从原始视图控制器到目标视图控制器。这个segue将手动执行。

当在菜单中选择目标选项时,让菜单自行消失,然后在源视图上执行目标segue,如下所示:

    // 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界面。

我在一个样例应用中测试了这个功能,其中“Menu”不是侧边栏,而是一个完整的模态视图控制器,测试成功。

编辑:与@KingTim一起进行故障排除时,他发现我们需要将segue从UINavigationController连接到Destination,而不是Origin。这是因为Origin位于导航控制器内部。发现这个问题后,功能正常工作。


谢谢,这很有趣 - 我尝试了一下,当我取消目标时,它回到了菜单,而不是起点。更具体地说,我将您的代码完全添加(除了我的segue名称不同)到处理菜单按钮被点击以呈现目标的IBAction中。 - KingTim
实际上,我误读了你的评论。你回答中的代码应该在Origin控制器中吗?我如何在Origin上调用Destination segue?通常我会在菜单按钮被按下的IBAction中调用segue,这显然是与Menu控制器连接的。 - KingTim
感谢更新。我仍然遇到崩溃:*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Receiver (<SpontiStoryboard.ChatViewController: 0x7fb6b102fe00>) has no segue with identifier 'chatToInvite'' <- 这发生在菜单自动关闭后。聊天(chat)为起点,邀请(invite)为目的地。 - KingTim
我已经设置了从聊天(源)到邀请(目标)的“chatToInvite”转场,并将您建议的代码放在菜单中按下邀请按钮的IBAction中。 - KingTim
我已经做了,仔细检查过并确保拼写正确:http://imgur.com/a/zF051 - KingTim
显示剩余9条评论

1
如果您的呈现视图嵌入了导航控制器,那么您可以这样做:
    weak var pvc:UIViewController! = self.presentingViewController?.childViewControllers[0]
    dismiss(animated: true)
    {
        pvc.performSegue(withIdentifier: "SegueID", sender: nil)
    }

0

通过使用 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)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接