Generic UIViewController subclass and XIB

Is it possible to use generic UIViewController subclass and use it with XIB? For example


import UIKit

protocol ViewModel {
    var title: String { get }
}

class ViewController<ViewModelType: ViewModel>: UIViewController {
    let viewModel: ViewModelType
   
    init(viewModel: ViewModelType, nibName: String) {
        self.viewModel = viewModel
       
        super.init(nibName: nibName, bundle: nil)
    }
   
    override func viewDidLoad() {
        super.viewDidLoad()
       
        title = viewModel.title
    }
}

class TestViewModel: ViewModel {
    let title: String
   
    init(title: String) {
        self.title = title
    }
}

class TestViewController: ViewController<TestViewModel> {
    init(viewModel: TestViewModel) {
        super.init(viewModel: viewModel, nibName: "TestViewController")
    }
}


Now the view controller is not loaded correctly from the XIB. I've been able to get it working by first defining TestViewController as UIViewController and then setting the outlest in interface builder. But should this even work?

Anyone?

Yes it is possible. I do it all the time. You may have to elaborate on "not loaded correctly". If the File's Owner is set correctly then all your outlets should be hooked up when UIKit loads the VC from the XIB.

I tried again and now it seems to work. I don't know what was wrong previously. Only problem is Interface Builder does not recognize the class as UIViewController subclass if I inherit it from generic UIViewController subclass like I said earlier.

hmm can't help on that part of it if it's a Swift specific issue with the generics. I'm still using Obj-C.

There is still something wrong. If I add another generic (ViewDecorator) in ViewController, the program crashes:


2015-09-21 12:31:30.125 Gener[12294:1190882] *** NSForwarding: warning: object 0x7f8da942d480 of class 'Gener.TestViewDecorator' does not implement methodSignatureForSelector: -- trouble ahead
Unrecognized selector -[Gener.TestViewDecorator layoutGuides]


The code:


class ViewController<ViewModelType: ViewModel, DecoratorType: ViewDecorator>: UIViewController {
    let viewModel: ViewModelType
    let decorator: DecoratorType

    init(viewModel: ViewModelType, decorator: DecoratorType, nibName: String) {
        self.viewModel = viewModel
        self.decorator = decorator
   
        super.init(nibName: nibName, bundle: nil)
    }

    override func viewDidLoad() {
        super.viewDidLoad()
   
        title = viewModel.title
   
        view.backgroundColor = decorator.backgroundColor
    }
}
protocol ViewModel {
    var title: String { get }
}
protocol ViewDecorator {
    var backgroundColor: UIColor? { get }
}

class TestViewController: ViewController<TestViewModel, TestViewDecorator> {
    init(viewModel: TestViewModel) {
        super.init(viewModel: viewModel, decorator: TestViewDecorator(), nibName: "TestViewController")
    }
}
class TestViewModel: ViewModel {
    var title: String { return "Test" }
}
class TestViewDecorator: ViewDecorator {
    var backgroundColor: UIColor? { return .redColor() }
}

I got it working by defining ViewModel and ViewDecorator as class-only protocols. Why is that needed?

Generic UIViewController subclass and XIB
 
 
Q