使用Generic将Storyboard链接到UIViewController

Sim*_*lGy 3 interface-builder ios

我有这个视图控制器,用于以通用方式呈现模型对象的详细信息:

class APIModelDetailsVC<T where T: APIModel>: UIViewController {...}
Run Code Online (Sandbox Code Playgroud)

我希望我的故事板能够使用这个课程.我可以在Interface Builder中分配它:

在此输入图像描述

我在tableview的didSelect方法中准备了这个ViewController(包括指定通用占位符的类型):

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
  print("didSelectRowAtIndexPath \(indexPath.row)")
  if let vc = UIStoryboard(name: "APIModelDetailsVC", bundle: nil).instantiateInitialViewController() as? APIModelDetailsVC<StarWarsPerson> {
    vc.model = data[indexPath.row]
    self.navigationController?.pushViewController(vc, animated: true)
  }
}
Run Code Online (Sandbox Code Playgroud)

当我尝试导航到此视图控制器时,出现以下控制台错误:

Unknown class _TtC14api_collection17APIModelDetailsVC in Interface Builder file.
Run Code Online (Sandbox Code Playgroud)

这是故事板的记录限制吗?有没有一种方法可以/应该指定通用,以便故事板可以链接到它?

Fed*_*eda 10

故事板有一个泛型类的问题.问题是Interface Builder通过Objective-C运行时与ViewController进行通信.因此,InterfaceBuilder仅限于Objective-C提供的功能.在这种情况下,不支持泛型.

解决方法是使用.load()方法NSObject.

例如,如果您有上面提到的ViewController类:

class APIModelDetailsVC<T where T: APIModel>: UIViewController {...}
Run Code Online (Sandbox Code Playgroud)

您应该创建一个"虚拟"ViewController,例如:

class StartWasModelDetailsVC: APIModelDetailsVC<StarWarsPerson> {...}
Run Code Online (Sandbox Code Playgroud)

并在故事板中设置最后一个ViewController.之后,为了在Objective-c运行时中进行此操作,您应该在AppDelegate中添加以下内容或在加载此控制器之前的某处.

StartWasModelDetailsVC.load()
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你!