0

I'm trying to change type of root UIView of my base UIViewController to my custom class. It's easy in storyboard.

enter image description here

But I need to do it programmatically.

I've tried to override loadView of my base class and replace the root view but the IBOutlets of child viewControllers get nil.

class FPViewController: UIViewController {

    override func loadView() {
        super.loadView()

        let tmpRootView = self.view ?? UIView()

        let gradient = UIView(frame: tmpRootView.frame)
        gradient.backgroundColor = .green
        view = gradient

        view.addSubview(tmpRootView)
    }
}
Seifolahi
  • 919
  • 3
  • 11
  • 26
  • Possible duplicate of [Replacing a UIViewController root view with my own view](https://stackoverflow.com/questions/1563885/replacing-a-uiviewcontroller-root-view-with-my-own-view) – Sagar Chauhan Jan 22 '19 at 12:48
  • I've seen that link. my outlets get nil after overriding loadview. – Seifolahi Jan 22 '19 at 12:52
  • @Chris But I'm Keeping the reference to the view and using it again. It shouldn't be deallocated. – Seifolahi Jan 22 '19 at 13:50
  • @Seifolahi I had missed that detail. Comment removed. See Duncan C's answer. – Chris Jan 22 '19 at 13:53

1 Answers1

0

By overriding loadView, you bypass the automatic mechanism for loading your view controller's views from a XIB or storyboard. That machanism is what connects up the outlets.

If you implement loadView, the burden is on you to do that housekeeping yourself.

Duncan C
  • 128,072
  • 22
  • 173
  • 272
  • I've thought about it. That's why I've called super.loadView() in first line. – Seifolahi Jan 22 '19 at 13:15
  • 1
    Quoting the docs on `loadView()`: "**If you use Interface Builder to create your views and initialize the view controller, you must not override this method.** You can override this method in order to create your views manually. If you choose to do so, assign the root view of your view hierarchy to the view property. The views you create should be unique instances and should not be shared with any other view controller object. **Your custom implementation of this method should not call super.**" (emphasis added.) – Duncan C Jan 22 '19 at 13:49
  • 1
    So the answer is "Don't do that." Either load your views from a nib/storyboard, and don't implement `loadView()`, or build your view hierarchy "from scratch" in `loadView()`, including connecting your outlets, and don't try to call `super.loadView()`. – Duncan C Jan 22 '19 at 13:50
  • That might be true. Then how can I achieve this and replace all root views of my viewcontrollers? – Seifolahi Jan 22 '19 at 13:57
  • 1
    As I said, "build your view hierarchy 'from scratch' in `loadView()`, including connecting your outlets, and don't try to call `super.loadView()`." – Duncan C Jan 22 '19 at 14:53