如何在由导航控制器显示的视图中,从容器视图执行转场操作?

5

Storyboard

我想从一个视图容器中的 "H" 跳转,该视图容器使用连接到分割视图控制器的导航控制器呈现。我该如何实现这一点?我尝试过使用本地链接的故事板ID进行常规 performSegueWithIdentifier 操作,但这会删除顶部导航栏。我想保留顶部导航栏,并执行 segue,就像使用主导航控制器(选择在详细视图中呈现哪个视图控制器的行)时所做的那样。

非常感谢您的帮助!

2个回答

12

这是从嵌入的视图控制器执行segue的示例。

示例Storyboard


ViewController.swift

import UIKit

protocol SegueHandler: class {
    func segueToNext(identifier: String)
}

class ViewController: UIViewController, SegueHandler {

    func segueToNext(identifier: String) {
        self.performSegueWithIdentifier(identifier, sender: self)
    }

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "EmbedH" {
            let dvc = segue.destinationViewController as! HViewController
            dvc.delegate = self
        }
    }
}

HViewController.swift

import UIKit

class HViewController: UIViewController {

    weak var delegate: SegueHandler?

    @IBAction func pressH(sender: UIButton) {
        delegate?.segueToNext("GoToGreen")
    }

}

设置:

  1. 使用委托将 HViewController 告诉其嵌入的视图控制器执行转场。
  2. 创建一个名为 SegueHandler 的协议,该协议仅描述了实现方法 segueToNext(identifier: String) 的类。

protocol SegueHandler: class {
    func segueToNext(identifier: String)
}
  • 将此协议添加到 class 声明行中,使您的视图控制器实现此协议:

  • class ViewController: UIViewController, SegueHandler {
    

    通过实现所需的函数来实现。

  • HViewController添加delegate属性:

  • weak var delegate: SegueHandler?
    
  • 在 ViewController 和 HViewController 之间点击嵌入(embed)segue箭头。在属性检查器中赋予它标识符"EmbedH"

  • 通过从 ViewController 顶部的 viewController 图标 Control 拖动到 GreenViewController,创建一个show segue。在属性检查器中将此segue命名为"GoToGreen"

  • 在ViewController 的prepareForSegue中,当发生"EmbedH" segue时,将HViewControllerdelegate属性设置为self(即ViewController)。

  • 当用户在HViewController中点击H按钮时,调用delegate?.segueToNext("GoToGreen")以触发ViewController中的segue。


  • 以下是模拟器演示:

    Simulator Demonstration


    首先,非常感谢您详细的回复。 :) 我将尝试在今天晚些时候实现它,并查看是否可以在我的测试应用程序中使其正常工作。顺便说一下,我通过在适当的故事板中添加“显示详细信息Segue”来获得预期的行为。然后,当我调用“self.performSegueWithIdentifier”时,它会保留导航栏和按钮的功能(保留视图历史记录等)。这种做法有什么问题吗? - Plastus
    我不太清楚你是如何做到的。如果你所做的有效,也可以将其作为答案添加(在 Stack Overflow 上,你可以回答自己的问题)。在你的答案中要具体说明你是如何设置转场以及如何从哪里调用它们。 - vacawama
    所以我的方法每次从主导航控制器中调用时都会销毁/实例化一个新的视图控制器(而不是在主应用程序VC内部)。这不好,因为我想在那里保留任何用户数据更改。我尝试实现您的方法,但当我点击按钮时它就停在那里。既不调用“prepareForSegue”也不调用“segueToNext”。与“HViewController”相当的内容在我之前上传的图片上的“H”故事板引用中。 - Plastus
    是时候进行调试了。在每个阶段放置打印语句或设置断点。确保一切都按照您的预期发生。 - vacawama
    我的事件流程是这样的,这会有问题吗?MenuVC -> 主页故事板引用 -> 主页 VC -> 子 VC。基本上,我要求 Child VC 执行一个 segue,就像 MenuVC 执行一样。 - Plastus
    显示剩余5条评论

    0

    我需要的正是@vacawama在这里提出的,尽管我无法复制它,但我按照您的步骤尝试了一下,但是self.delegate?.segueToNext("GoToGreen")被调用,但既不是协议本身也不是容器视图控制器。经过整整一天搜索这种方法,我意识到问题出在swift版本上。只需替换此内容:

    func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "EmbedH" {
            let dvc = segue.destination as! HViewController
            dvc.delegate = self
        }
    }
    

    对于这个:

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "EmbedH" {
            let dvc = segue.destination as! HViewController
            dvc.delegate = self
        }
    }
    

    另外我遗漏的细节是关于嵌入式转场的。请确保将容器视图连接到 HViewController,而不是视图控制器本身,否则转场选项中的嵌入选项将不会出现。

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