Issue #37
I like to write UI in code, and with Auto Layout, it is an easy task. However that leaves ViewController with a lots of code. One way we can do is to separate V
from C
in MVC
, by using a dedicated view
We can do that with generic, that initialises a view and replace the view
, let’s call it root
1 2 3 4 5 6 7 8 9 import UIKitclass BaseController <T : UIView >: UIViewController { let root = T () override func loadView () { view = root } }
Now we can have a UIView
subclass, like LoginView
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 final class LoginView : UIView { lazy var textField: UITextField = UITextField ().then { $0 .textAlignment = .center $0 .borderStyle = .roundedRect $0 .keyboardType = .phonePad } lazy var button: UIButton = UIButton ().then { $0 .setTitleColor(.black, for : .normal) $0 .backgroundColor = .lightGray } override init (frame: CGRect ) { super .init (frame: frame) addSubviews( textField, button ) Constraint .on( textField.centerXAnchor.constraint(equalTo: textField.superview!.centerXAnchor), textField.centerYAnchor.constraint(equalTo: textField.superview!.centerYAnchor), textField.widthAnchor.constraint(equalTo: textField.superview!.widthAnchor, constant: -20 ), button.topAnchor.constraint(equalTo: textField.bottomAnchor, constant: 20 ), button.centerXAnchor.constraint(equalTo: button.superview!.centerXAnchor), button.widthAnchor.constraint(equalTo: textField.widthAnchor, multiplier: 0.8 ), button.heightAnchor.constraint(equalToConstant: 44 ) ) } required init ?(coder aDecoder: NSCoder ) { fatalError () } }
And then the LoginController
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 final class LoginController : BaseController <LoginView > { override func viewDidLoad () { super .viewDidLoad() view.backgroundColor = .white let gr = UITapGestureRecognizer (target: self , action: #selector(viewTapped)) root.addGestureRecognizer(gr) root.button.setTitle("Login" , for : .normal) root.button.addTarget(self , action: #selector(loginButtonTouched), for : .touchUpInside) root.button.isEnabled = false root.button.showsTouchWhenHighlighted = true root.textField.placeholder = "Phone number" root.textField.delegate = self root.textField.text = dependencyContainer.phoneService.prefix root.textField.addTarget(self , action: #selector(textFieldDidChange), for : .editingChanged) } }
And this is how we declare the LoginController
1 2 let loginController = LoginController ()navigationController.viewControllers = [loginController]