【问题标题】:how to segue to storyboard viewcontroller from xib view with swift 3如何使用 swift 3 从 xib 视图转到情节提要视图控制器
【发布时间】:2017-07-08 09:23:27
【问题描述】:

我很难找到答案。

我有一个 xib 视图,它位于视图控制器内的滚动视图中。在 xib 中,我有一个带有操作的按钮,我需要转到我的故事板中的视图控制器。我也希望能够使用自定义转场。

到目前为止,我已经读到我可以从情节提要中实例化视图控制器以继续它。但是我不知道如何呈现该控制器。

感谢您的帮助...

更新:

这是我用来执行转场的代码。

在父视图控制器中:

    static var referenceVC: UIViewController?


override func viewDidLoad() {
    super.viewDidLoad()
    print("viewdidload")
    LevelSelectViewController.referenceVC = self

    setupScrollView()
}

xib 视图文件中的代码

        let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "sightWordController")

        let parent = LevelSelectViewController.referenceVC!

        let segue = InFromRightCustomSegue(identifier: "test", source: parent, destination: vc)


        segue.perform()

【问题讨论】:

  • Segues 通常仅限于情节提要使用。您可能必须以某种方式将您的视图(您可以将视图的整个类配置为从 nib 加载)添加到情节提要中,然后您可以将 segue 连接到它。否则,出于某种原因,它们被称为UIStoryboardSegues。
  • 如果您使用可以在代码中分配的自定义 segue,我相信您只需要一个 VC 来执行,这意味着您可以爬上响应者链找到相关的 VC 来执行它。但总的来说,听起来您想要自定义转换和某种委托回调。绝对没有理由让您的代码如此复杂以保持连续性。
  • 我刚刚开始工作。我最大的问题是获得对父视图控制器的引用,以便我可以调用 segue。我获得引用的方式有点小技巧,我只是在父视图控制器中创建了一个静态引用变量,我可以在 xib 文件中使用它。有没有更好的方法来获取参考?我将更新问题以显示我的代码。
  • 如果您希望引用是通用的(例如常规的 segue),只需爬上响应者链以查看哪个 VC 想要处理/可以处理首先呈现或执行 segue。
  • 如果你想/需要不那么通用,你也可以使用委托来通知 VC 一个动作已经发生并且它应该响应。

标签: swift storyboard segue xib


【解决方案1】:

如 cmets 中所述,Segues 通常仅限于情节提要使用,如 documentation 中所述。您可以通过@IBDesignable 之类的方法在情节提要中实现自定义 xib 视图,并让您将视图从 xib 加载到情节提要文件/类中。这样,您将获得两全其美的好处。否则,您可能希望以另一种方式处理此问题(例如 delegates/target-action 事件等)。

您还可以爬上responder chain 并通过获取对 VC 的引用并调用 segue 来调用与从情节提要加载的 VC 相关的 segue(segue 不一定必须附加到任何特定操作) .您可以通过以下示例代码的方式爬上响应者链:

protocol ChildViewControllerContainer {
    var parentViewController: UIViewController? { get }
}


protocol ViewControllerTraversable {
    func viewController<T: UIViewController>() -> T?
}

extension UIView: ViewControllerTraversable {

    func viewController<T: UIViewController>() -> T? {
        var responder = next

        while let currentResponder = responder {
            guard responder is T else {
                responder = currentResponder.next
                continue
            }

            break
        }

        return responder as? T
    }
}

extension UITableViewCell: ChildViewControllerContainer {
    weak var parentViewController: UIViewController? {
        return viewController() as UIViewController?
    }
}

【讨论】:

  • 感谢您的回复,我会调查此事。它现在肯定看起来在我的头上。你觉得我的做法有什么问题吗?我编辑了我的问题以包含我用来让它工作的代码
  • 您绝对不应该像引用父 VC 那样引用静态变量。上面的代码解决了这个问题。
  • 是否可以在代码中包含 cmets 以帮助我更好地了解正在发生的事情?
  • 我宁愿鼓励您运行代码并逐步执行它。只需将此代码添加到您的自定义视图文件中,然后调用 myCustomView.viewController 作为 UIViewController
  • 好的,我会这样做的。感谢您的代码。如果遇到问题,我会通知您。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-16
  • 1970-01-01
  • 2013-10-21
  • 2012-12-18
  • 2017-11-14
  • 1970-01-01
相关资源
最近更新 更多