There seem to be two questions here. One of them is the best way to programmatically configure the ViewController. Another is how to set up the program view.
First, the best way to have a ViewController programmatically using another subclass of UIView is to initialize and assign it in the loadView method. Per Apple docs :
You can override this method to manually create your views. If you decide to do this, assign the view property to the root view of your view hierarchy. The views you create must be unique instances and should not be used in conjunction with any other view controller object. Your custom implementation of this method should not be called super.
It will look something like this:
class LoginViewController: UIViewController { override func loadView() {
This way, you donβt have to deal with its calibration, since the view controller itself needs to take care of this (as its own UIView does).
Remember, do not call super.loadView() , or the controller will be confused. Also, the first time I tried this, I got a black screen because I forgot to call window.makeKeyAndVisible() in the App Delegate app. In this case, the view was never added to the window hierarchy. You can always use the preview introspector button in Xcode to find out what happens.
Secondly, you will need to call self.addSubview(_:) in your UIView subclass to display them. When you add them as subzones, you can add constraints using NSLayoutConstraint .
private func setupLabels(){ // Initialize labels and set their text usernameLabel = UILabel() usernameLabel.text = "Username" usernameLabel.translatesAutoresizingMaskIntoConstraints = false // Necessary because this view wasn't instantiated by IB addSubview(usernameLabel) passwordLabel = UILabel() passwordLabel.text = "Password" passwordLabel.translatesAutoresizingMaskIntoConstraints = false // Necessary because this view wasn't instantiated by IB addSubview(passwordLabel) NSLayoutConstraint.activate(NSLayoutConstraint.constraints(withVisualFormat: "V:|-10-[view]", options: [], metrics: nil, views: ["view":usernameLabel])) NSLayoutConstraint.activate(NSLayoutConstraint.constraints(withVisualFormat: "V:|-20-[view]", options: [], metrics: nil, views: ["view":passwordLabel])) NSLayoutConstraint.activate(NSLayoutConstraint.constraints(withVisualFormat: "H:|-10-[view]", options: [], metrics: nil, views: ["view":usernameLabel])) NSLayoutConstraint.activate(NSLayoutConstraint.constraints(withVisualFormat: "H:|-20-[view]", options: [], metrics: nil, views: ["view":passwordLabel])) }
For more information about the visual format language used to create constraints, see the VFL Guide