Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Link Storyboard to UIViewController with Generic

I have this view controller, meant to present model object details in a generic way:

class APIModelDetailsVC<T where T: APIModel>: UIViewController {...}

I'd like my storyboard to use this class. I'm able to assign it in Interface Builder:

enter image description here

I do the preparation of this ViewController in a tableview's didSelect method (including specifying the type for the generic placeholder):

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)
  }
}

When I attempt to navigate to this view controller, I get the following console error:

Unknown class _TtC14api_collection17APIModelDetailsVC in Interface Builder file.

Is this a documented limitation with Storyboards? Is there a way I can/should specify the generic so the storyboard can link to it?

like image 537
SimplGy Avatar asked May 17 '16 17:05

SimplGy


People also ask

How do I add a Viewcontroller to a storyboard?

To create a new view controller, select File->New->File and select a Cocoa Touch Class. Choose whether to create it with Swift or Objective-C and inherit from UIViewController . Don't create it with a xib (a separate Interface Builder file), as you will most likely add it to an existing storyboard.

How do I get a view's Viewcontroller?

If you need to find the view controller that is responsible for a particular view, the easiest thing to do is walk the responder chain. This chain is built into all iOS apps, and lets you walk from one view up to its parent view, its grandparent view, and so on, until it reaches a view controller.

What is storyboard UIKit?

Storyboard allows us to add UI elements to the screen by simply dragging and dropping. To create a project in UIKit with Storyboard, we select Storyboard in the Xcode project Interface dropdown: Using the Interface Builder, we add UI elements to the screen, as shown in the below video.

What is a UIViewController?

The UIViewController class defines the methods and properties for managing your views, handling events, transitioning from one view controller to another, and coordinating with other parts of your app.


1 Answers

Storyboards have a problem with having a generic class. The thing is that Interface Builder communicates to the ViewController through the Objective-C runtime. Because of this, InterfaceBuilder is limited to the features that Objective-C provides. In this case, generics are not supported.

A workaround for this is using the .load() method of NSObject.

For example, if you have the mentioned ViewController class:

class APIModelDetailsVC<T where T: APIModel>: UIViewController {...}

You should create a "dummy" ViewController such as:

class StartWasModelDetailsVC: APIModelDetailsVC<StarWarsPerson> {...}

and set this last ViewController in the storyboard. Afterwards, in order to make this work in the Objective-c runtime, you should add the following in your AppDelegate or somewhere before this controller is loaded.

StartWasModelDetailsVC.load()

Hope it helps!

like image 153
Federico Ojeda Avatar answered Nov 12 '22 02:11

Federico Ojeda