In my previous post, I wrote about some libraries used to do AutoLayout in code. Finally, I decided to use SnapKit in a small app. Here is the code and the screens, hope you find this useful. (logos are blacked out). I’m only showing the parts of the code related to SnapKit, so do not expect to copy, paste, and run it 😛

HeaderViewController: all view controller inherits from this class, it contains the header part of the screen.

class HeaderViewController: UIViewController { let header = UIView() let logo = UIImageView() let subLogos = UIImageView() func initHeader() { initHeaderView() initLogoImageView() initSubLogosImageView() setBackgroundColor() } private func initHeaderView() { view.addSubview(header) header.backgroundColor = UIColor(hex: "#575353") header.snp.makeConstraints { make in make.top.equalToSuperview() make.left.equalToSuperview() make.right.equalToSuperview() make.height.equalTo(view.snp.height).dividedBy(3) } } private func initLogoImageView() { header.addSubview(logo) logo.image = UIImage(named: "logo_it_point") logo.contentMode = .scaleAspectFit logo.snp.makeConstraints { make in make.topMargin.equalTo(30) make.centerX.equalToSuperview() } } private func initSubLogosImageView() { header.addSubview(subLogos) subLogos.image = UIImage(named: "logos_white") subLogos.contentMode = .scaleAspectFit subLogos.snp.makeConstraints { make in make.top.equalTo(logo.snp.bottom) make.left.equalToSuperview().offset(8) make.right.equalToSuperview().inset(8) make.bottom.equalToSuperview() make.height.equalToSuperview().dividedBy(5) } } private func setBackgroundColor() { view.backgroundColor = UIColor(hex: "#F5F5F5") } }

Login screen

class LoginViewController: HeaderViewController { let usernameLabel = UILabel() let usernameTextField = UITextField() let passwordLabel = UILabel() let passwordTextField = UITextField() let tokenLabel = UILabel() let tokenTextField = UITextField() let loginButton = UIButton() override func viewDidLoad() { super.viewDidLoad() initUI() } private func initUI() { initHeader() initUsernameLabel() initUsernameTextField() initPasswordLabel() initPasswordTextField() initTokenLabel() initTokenTextField() initLoginButton() } private func initUsernameLabel() { view.addSubview(usernameLabel) usernameLabel.text = "Usuario" usernameLabel.font = UIFont.systemFont(ofSize: 12) usernameLabel.snp.makeConstraints { make in make.leftMargin.equalTo(24) make.topMargin.equalTo(header.snp.bottom).offset(36) } } private func initUsernameTextField() { view.addSubview(usernameTextField) usernameTextField.borderStyle = .roundedRect usernameTextField.autocapitalizationType = .none usernameTextField.autocorrectionType = .no usernameTextField.snp.makeConstraints { make in make.leftMargin.equalTo(24) make.rightMargin.equalTo(-24) make.top.equalTo(usernameLabel.snp.bottom).offset(6) } } private func initPasswordLabel() { view.addSubview(passwordLabel) passwordLabel.text = "Clave" passwordLabel.font = UIFont.systemFont(ofSize: 12) passwordLabel.snp.makeConstraints { make in make.leftMargin.equalTo(24) make.top.equalTo(usernameTextField.snp.bottom).offset(24) } } private func initPasswordTextField() { view.addSubview(passwordTextField) passwordTextField.borderStyle = .roundedRect passwordTextField.isSecureTextEntry = true passwordTextField.snp.makeConstraints { make in make.leftMargin.equalTo(24) make.rightMargin.equalTo(-24) make.top.equalTo(passwordLabel.snp.bottom).offset(6) } } private func initTokenLabel() { view.addSubview(tokenLabel) tokenLabel.text = "Token" tokenLabel.font = UIFont.systemFont(ofSize: 12) tokenLabel.snp.makeConstraints { make in make.leftMargin.equalTo(24) make.top.equalTo(passwordTextField.snp.bottom).offset(24) } } private func initTokenTextField() { view.addSubview(tokenTextField) tokenTextField.borderStyle = .roundedRect tokenTextField.autocapitalizationType = .none tokenTextField.autocorrectionType = .no tokenTextField.snp.makeConstraints { make in make.leftMargin.equalTo(24) make.rightMargin.equalTo(-24) make.top.equalTo(tokenLabel.snp.bottom).offset(6) } } private func initLoginButton() { view.addSubview(loginButton) loginButton.setTitle("Ingresar", for: .normal) loginButton.backgroundColor = UIColor(hex: "#4098C8") loginButton.addTarget(self, action: #selector(loginButtonClicked(sender:)), for: .touchUpInside) loginButton.snp.makeConstraints { make in make.top.equalTo(tokenTextField.snp.bottom).offset(36) make.width.equalToSuperview().dividedBy(3) make.centerX.equalToSuperview() } } }

Tickets list screen

class TicketsListViewController: HeaderViewController { let newTicketButton = UIButton() let ticketsHistoryLabel = UILabel() let tableView = UITableView() override func viewDidLoad() { super.viewDidLoad() initUI() } private func initUI() { initHeader() initNewTicketButton() initTicketsHistoryLabel() initTableView() } private func initNewTicketButton() { view.addSubview(newTicketButton) newTicketButton.setTitle("Nuevo Ticket", for: .normal) newTicketButton.backgroundColor = UIColor(hex: "#4098C8") newTicketButton.addTarget(self, action: #selector(newTicketButtonClicked(sender:)), for: .touchUpInside) newTicketButton.snp.makeConstraints { make in make.left.equalToSuperview().offset(8) make.right.equalToSuperview().inset(8) make.top.equalTo(header.snp.bottom).offset(8) } } private func initTicketsHistoryLabel() { view.addSubview(ticketsHistoryLabel) ticketsHistoryLabel.text = "Historial de tickets" ticketsHistoryLabel.font = UIFont.systemFont(ofSize: 14) ticketsHistoryLabel.snp.makeConstraints { make in make.top.equalTo(newTicketButton.snp.bottom).offset(12) make.centerX.equalToSuperview() } } private func initTableView() { view.addSubview(tableView) tableView.backgroundColor = UIColor(hex: "#F5F5F5") tableView.delegate = self tableView.dataSource = self tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell") tableView.separatorColor = UIColor.clear tableView.snp.makeConstraints { make in make.top.equalTo(ticketsHistoryLabel.snp.bottom).offset(6) make.left.equalToSuperview() make.right.equalToSuperview() make.bottom.equalToSuperview() } } }

New ticket screen

class NewTicketViewController: HeaderViewController { let newTicketLabel = UILabel() let newTicketImageView = UIImageView() let ticketTypesLabel = UILabel() let ticketTypesTextField = UITextField() let ticketTypesPickerView = UIPickerView() let notesLabel = UILabel() let notesTextView = UITextView() let backButton = UIButton() let saveButton = UIButton() override func viewDidLoad() { super.viewDidLoad() initUI() } private func initUI() { initHeader() initNewTicketLabel() initNewTicketImageView() initTicketTypesLabel() initTicketTypesTextField() initNotesLabel() initNotesTextView() initBackButton() initSaveButton() } private func initNewTicketLabel() { view.addSubview(newTicketLabel) newTicketLabel.text = "Nuevo Ticket" newTicketLabel.font = UIFont.systemFont(ofSize: 14) newTicketLabel.snp.makeConstraints { make in make.top.equalTo(header.snp.bottom).offset(16) make.centerX.equalToSuperview().offset(12) } } private func initNewTicketImageView() { view.addSubview(newTicketImageView) newTicketImageView.image = UIImage(named: "mini_logo") newTicketImageView.contentMode = .scaleAspectFit newTicketImageView.snp.makeConstraints { make in make.height.equalTo(24) make.centerY.equalTo(newTicketLabel.snp.centerY) make.right.equalTo(newTicketLabel.snp.left) } } private func initTicketTypesLabel() { view.addSubview(ticketTypesLabel) ticketTypesLabel.text = "Tipo" ticketTypesLabel.font = UIFont.systemFont(ofSize: 12) ticketTypesLabel.snp.makeConstraints { make in make.leftMargin.equalTo(16) make.top.equalTo(newTicketLabel.snp.bottom).offset(12) } } private func initTicketTypesTextField() { view.addSubview(ticketTypesTextField) ticketTypesTextField.borderStyle = .roundedRect ticketTypesTextField.autocapitalizationType = .none ticketTypesTextField.autocorrectionType = .no ticketTypesTextField.inputView = ticketTypesPickerView ticketTypesTextField.setCustomDoneTarget(self, action: #selector(doneClickedForTicketTypesTextField(sender:))) ticketTypesTextField.snp.makeConstraints { make in make.leftMargin.equalTo(16) make.rightMargin.equalTo(-16) make.top.equalTo(ticketTypesLabel.snp.bottom).offset(6) } } private func initNotesLabel() { view.addSubview(notesLabel) notesLabel.text = "Observaciones" notesLabel.font = UIFont.systemFont(ofSize: 12) notesLabel.snp.makeConstraints { make in make.leftMargin.equalTo(16) make.top.equalTo(ticketTypesTextField.snp.bottom).offset(12) } } private func initNotesTextView() { view.addSubview(notesTextView) notesTextView.bordered() notesTextView.autocapitalizationType = .none notesTextView.autocorrectionType = .no notesTextView.snp.makeConstraints { make in make.leftMargin.equalTo(16) make.rightMargin.equalTo(-16) make.top.equalTo(notesLabel.snp.bottom).offset(6) make.height.equalTo(100) } } private func initBackButton() { view.addSubview(backButton) backButton.setTitle("Atras", for: .normal) backButton.backgroundColor = UIColor(hex: "#4098C8") backButton.addTarget(self, action: #selector(backButtonClicked(sender:)), for: .touchUpInside) backButton.snp.makeConstraints { make in make.top.equalTo(notesTextView.snp.bottom).offset(16) make.left.equalTo(notesTextView.snp.left) } } private func initSaveButton() { view.addSubview(saveButton) saveButton.setTitle("Guardar", for: .normal) saveButton.backgroundColor = UIColor(hex: "#4098C8") saveButton.addTarget(self, action: #selector(saveButtonClicked(sender:)), for: .touchUpInside) saveButton.snp.makeConstraints { make in make.top.equalTo(notesTextView.snp.bottom).offset(16) make.right.equalTo(notesTextView.snp.right) make.left.equalTo(backButton.snp.right).offset(6) make.width.equalTo(backButton.snp.width) } } }

Ticket detail screen