Using SnapKit on a real app

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

jahskdash

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

lkqjwelk

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

kjalska

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

jsdhfkjds

class TicketDetailViewController: HeaderViewController
{
    let ticketDetailLabel = UILabel()
    let ticketDetailImageView = UIImageView()
    let cardView = CardView()
    let dateTimeLabel = UILabel()
    let dateTimeValueLabel = UILabel()
    let ticketTypeDescriptionLabel = UILabel()
    let ticketTypeDescriptionValueLabel = UILabel()
    let notesLabel = UILabel()
    let notesValueLabel = UILabel()
    let backButton = UIButton()
    let newTicketButton = UIButton()

    override func viewDidLoad()
    {
        super.viewDidLoad()
        initUI()
    }
 
    private func initUI()
    {
        initHeader()
        initTicketDetailLabel()
        initTicketDetailImageView()
        initCardView()
        initDateTimeLabel()
        initDateTimeValueLabel()
        initTicketTypeDescriptionLabel()
        initTicketTypeDescriptionValueLabel()
        initNotesLabel()
        initNotesValueLabel()
        initBackButton()
        initNewTicketButton()
    }
 
    private func initTicketDetailLabel()
    {
        view.addSubview(ticketDetailLabel)
        ticketDetailLabel.text = "Detalle del Ticket"
        ticketDetailLabel.font = UIFont.systemFont(ofSize: 14)
        ticketDetailLabel.snp.makeConstraints { make in
            make.top.equalTo(header.snp.bottom).offset(16)
            make.centerX.equalToSuperview().offset(12)
        }
    }
 
    private func initTicketDetailImageView()
    {
        view.addSubview(ticketDetailImageView)
        ticketDetailImageView.image = UIImage(named: "mini_logo")
        ticketDetailImageView.contentMode = .scaleAspectFit
        ticketDetailImageView.snp.makeConstraints { make in
            make.height.equalTo(24)
            make.centerY.equalTo(ticketDetailLabel.snp.centerY)
            make.right.equalTo(ticketDetailLabel.snp.left)
        }
    }
 
    private func initCardView()
    {
        view.addSubview(cardView)
        cardView.backgroundColor = .white
        cardView.snp.makeConstraints { make in
            make.leftMargin.equalToSuperview().offset(16)
            make.rightMargin.equalToSuperview().inset(16)
            make.top.equalTo(ticketDetailLabel.snp.bottom).offset(18)
        }
    }
 
    private func initDateTimeLabel()
    {
        cardView.addSubview(dateTimeLabel)
        dateTimeLabel.text = "Fecha"
        dateTimeLabel.font = UIFont.systemFont(ofSize: 12)
        dateTimeLabel.snp.makeConstraints { make in
            make.left.equalToSuperview().offset(8)
            make.top.equalToSuperview().offset(8)
        }
    }
 
    private func initDateTimeValueLabel()
    {
        cardView.addSubview(dateTimeValueLabel)
        dateTimeValueLabel.font = UIFont.systemFont(ofSize: 12)
        dateTimeValueLabel.textColor = .lightGray
        dateTimeValueLabel.snp.makeConstraints { make in
            make.left.equalTo(dateTimeLabel.snp.right).offset(4)
            make.top.equalToSuperview().offset(8)
        }
    }
 
    private func initTicketTypeDescriptionLabel()
    {
        cardView.addSubview(ticketTypeDescriptionLabel)
        ticketTypeDescriptionLabel.text = "Tipo"
        ticketTypeDescriptionLabel.font = UIFont.systemFont(ofSize: 12)
        ticketTypeDescriptionLabel.snp.makeConstraints { make in
            make.left.equalToSuperview().offset(8)
            make.top.equalTo(dateTimeLabel.snp.bottom).offset(8)
        }
    }
 
    private func initTicketTypeDescriptionValueLabel()
    {
        cardView.addSubview(ticketTypeDescriptionValueLabel)
        ticketTypeDescriptionValueLabel.font = UIFont.systemFont(ofSize: 12)
        ticketTypeDescriptionValueLabel.textColor = .lightGray
        ticketTypeDescriptionValueLabel.snp.makeConstraints { make in
            make.left.equalTo(ticketTypeDescriptionLabel.snp.right).offset(4)
            make.top.equalTo(dateTimeValueLabel.snp.bottom).offset(8)
        }
    }
 
    private func initNotesLabel()
    {
        cardView.addSubview(notesLabel)
        notesLabel.text = "Observaciones"
        notesLabel.font = UIFont.systemFont(ofSize: 12)
        notesLabel.snp.makeConstraints { make in
            make.left.equalToSuperview().offset(8)
            make.top.equalTo(ticketTypeDescriptionLabel.snp.bottom).offset(8)
        }
    }
 
    private func initNotesValueLabel()
    {
        cardView.addSubview(notesValueLabel)
        notesValueLabel.font = UIFont.systemFont(ofSize: 12)
        notesValueLabel.textColor = .lightGray
        notesValueLabel.numberOfLines = 0
        notesValueLabel.snp.makeConstraints { make in
            make.left.equalToSuperview().offset(8)
            make.right.equalToSuperview().inset(8)
            make.top.equalTo(notesLabel.snp.bottom).offset(4)
            make.bottom.equalTo(cardView.snp.bottom).inset(8)
        }
    }
 
    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(cardView.snp.bottom).offset(16)
            make.left.equalTo(cardView.snp.left)
        }
    }

    private func initNewTicketButton()
    {
        view.addSubview(newTicketButton)
        newTicketButton.setTitle("Nuevo", for: .normal)
        newTicketButton.backgroundColor = UIColor(hex: "#4098C8")
        newTicketButton.addTarget(self, action: #selector(newTicketButtonClicked(sender:)), for: .touchUpInside)
        newTicketButton.snp.makeConstraints { make in
            make.top.equalTo(cardView.snp.bottom).offset(16)
            make.right.equalTo(cardView.snp.right)
            make.left.equalTo(backButton.snp.right).offset(6)
            make.width.equalTo(backButton.snp.width)
        }
    }
}
Advertisements
Using SnapKit on a real app

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s