来自UIStoryboardSegueTemplate的Destination ViewController

时间:2018-02-28 12:07:46

标签: ios swift

我正在尝试以编程方式使用UIStoryboardSegueTemplate将所有segue附加到UIViewController,我的目标是将目标视图控制器连接到相关的segue。

到目前为止,我已经完成了:

func initViewControllers(){

    guard let array = self.value(forKey: "storyboardSegueTemplates") as? [AnyObject] else {
        //No segues
        return
    }

    for item in array{
        print("\(logClassName): initViewControllers -> Self = \(String(describing: item.self))")
        print("\(logClassName): initViewControllers -> Segue Identifier = \(String(describing: item.value(forKey: "identifier")))")
        print("\(logClassName): initViewControllers -> Class = \(String(describing: item.value(forKey: "segueClassName")))")
        print("\(logClassName): initViewControllers -> Destination = \(String(describing: item.value(forKey: "destinationViewControllerIdentifier")))")


        let segueClassName:String = (item.value(forKey: "segueClassName") as? String) ?? ""
        if segueClassName.contains("CustomTabSegue"){
            print("\(logClassName): appending tabItem VC")
            let segueContainer:String = (item.value(forKey: "identifier") as? String) ?? ""
            performSegue(withIdentifier: segueContainer, sender: self)
        }

   }
}

并使用override func prepare(for segue: UIStoryboardSegue, sender: Any?)

获取目的地

我选择要捕获的segues的方式是通过名为CustomTabSegue

的自定义类

问题是:有没有办法在不执行segue的情况下获取目标View控制器?

根据这个link似乎不太可能,但也许有些东西我不知道。

2 个答案:

答案 0 :(得分:1)

如果您自己创建了这些segues,我做了什么,我将标识符给了segue: -

ViewControllerName1 + "To" + ViewControllerName2

storyboardSegueTemplates 获取segue列表后,我将它们与To分开,得到了源和目标ViewControllers的名称。然后,按

将它们转换为类型
NSClassFromString(ClassName: String)

通过这种方式,您可以获得与segue相关联的类的类型,但是无法获取 destinationViewControllers 的实例,因为它们在您执行之前不会被初始化:

 performSegue(withIdentifier: String, sender: Any?)

希望它有所帮助!!

答案 1 :(得分:0)

根据史密斯特工的回答,我能够做到:

func initViewControllers(){

    guard let array = self.value(forKey: "storyboardSegueTemplates") as? [AnyObject] else {
        return
    }

    for item in array{

        if let segueClassName = (item.value(forKey: "segueClassName") as? String){

            if segueClassName.contains("CustomTabSegue"){
                print("\(logClassName): CustomTabSegue")

                if let destinationViewController = (item.value(forKey: "destinationViewControllerIdentifier") as? String)?.components(separatedBy: "-").first{
                    print("\(logClassName): DestinationVC = \(destinationViewController)")

                    if let addedVC = destinationViewController.getViewController(){
                        print("\(logClassName): Adding View Controller \(addedVC.logClassName)")
                        viewControllers.append(addedVC)
                    }

                }
            }
        }
}

我创建了以下扩展

import Foundation
import UIKit

extension String{

func getViewController() -> UIViewController? {

    if var appName = Bundle.main.infoDictionary?["CFBundleName"] as? String {
        print("CFBundleName - \(appName)")
        appName = appName.replacingOccurrences(of: " ", with: "_", options: .literal)

        if let viewControllerType = NSClassFromString("\(appName).\(self)") as? UIViewController.Type {
            print("String: as UIViewController")
            return viewControllerType.init()
        }

    }

    return nil
}

它按预期工作但现在唯一的问题是如果嵌入在UINavigationController中的ViewController它不会检测到它