class ViewController: UIViewController {
private lazy var submitBtn: UIButton = {
let b = UIButton(type: .system)
b.translatesAutoresizingMaskIntoConstraints = false
b.setTitle("Submit", for: .normal)
return b
}()
deinit {
NotificationCenter.default.removeObserver(self)
}
override func loadView() {
super.loadView()
initUI()
initConstraints()
}
override func viewDidLayoutSubviews() {
initStyle()
}
override func viewDidLoad() {
super.viewDidLoad()
initDelegates()
initEvents()
initNotifications()
initData()
}
func initUI() {
self.view = UI.view() // set the view for the view controller
self.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
self.view.backgroundColor = UIColor.white // set the default view color to white
// add sub views...
}
}
class UI {
static func view() -> UIView {
let screenSize = UIScreen.main.bounds
let v = UIView(frame: CGRect(x: 0, y: 0, width: screenSize.width, height: screenSize.height))
v.backgroundColor = UIColor.white
return v
}
}
Here in loadView()
method, we initialise the UI using the initUI()
method, where we write any UI related code to display the view controller. We can use a static class UI.swift
for common UI related methods, which can be used from any view controller. We can then build the UI by adding subviews, with independent components as lazy variables, which can be accessed from other parts of the code for getting values, adding events to it and such. We can further customise this by moving all UI related code to a separate view class if the view controller has a lot of functionality.Once the UI is set up, next we need to add constraints. Constraints for each UI component will be added separately using the
NSLayoutConstraint.activate([])
method. Make sure that the UI components have translatesAutoresizingMaskIntoConstraints
set to false
.NSLayoutConstraint.activate([
submitBtn.topAnchor.constraint(equalTo: self.formView.bottomAnchor, constant: 8),
submitBtn.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 16),
submitBtn.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -16),
submitBtn.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: -8)
])
Here, the difference between programmatic constraint and storyboard is that the bottom and trailing units need to be in negative where as the same constraint when added in Interface Builder, we use positive values. In the viewDidLayoutSubviews()
method, we call initStyles()
to add any style to UI elements, at which point we will have the UI initialised properly with constraints and adding properties like border, color etc will work because the UI component's frame is not of CGRect.zero
. Once the constraints are setup, we will set the delegates of any UI components and objects. Then we add target-action for UI elements in initEvents()
method. If the view controller needs to listen to certain notifications, we add that in the initNotifications()
method. Next we call initData()
where we populate any model variables which is required for displaying, like in case of table view as well as making calls to service layer to fetch or update data.