// programmatic view controller /* usage: override func viewDidLoad() { super.viewDidLoad() let newViewController = NewViewController(string: "Hello") addChildViewController(newViewController, in: view) } */ class NewViewController: UIViewController { var string: String init(string: String) { self.string = string super.init(nibName: nil, bundle: nil) } override func loadView() { view = UIView() } // you can add other methods like `viewDidLoad` here // this method is boilerplate code but you always need to include it @available(*, unavailable) required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } } // useful extensions, including `addChildViewController` extension UIViewController { // add a view controller as a *subview* func addChildViewController(_ childViewController: UIViewController, in view: UIView) { addChild(childViewController) view.addSubview(childViewController.view) /// Configure child view childViewController.view.frame = view.bounds childViewController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight] /// Notify child view controller childViewController.didMove(toParent: self) } func removeChildViewController(_ childViewController: UIViewController) { /// Notify child view controller childViewController.willMove(toParent: nil) /// Remove child view from superview childViewController.view.removeFromSuperview() /// Notify child view controller again childViewController.removeFromParent() } } // lifesaver extension for pinning a view to its parent extension UIView { func pinEdgesToSuperview() { guard let superview = superview else { return } self.translatesAutoresizingMaskIntoConstraints = false // always remember this! NSLayoutConstraint.activate([ self.topAnchor.constraint(equalTo: superview.topAnchor), self.rightAnchor.constraint(equalTo: superview.rightAnchor), self.bottomAnchor.constraint(equalTo: superview.bottomAnchor), self.leftAnchor.constraint(equalTo: superview.leftAnchor) ]) } } // useful for debugging extension UIView { /// add a border to a view /// usage: `view.addDebugBorders(.red)` func addDebugBorders(_ color: UIColor, width: CGFloat = 0.75) { backgroundColor = color.withAlphaComponent(0.2) layer.borderColor = color.cgColor layer.borderWidth = width } }