Created
September 18, 2018 14:09
-
-
Save DanielCardonaRojas/add2cf8a816b366296913ebd3215b23d to your computer and use it in GitHub Desktop.
An example of a programmatic custom view
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// ProfileInputField.swift | |
// CustomViews | |
// | |
// Created by Daniel Esteban Cardona Rojas on 9/14/18. | |
// Copyright © 2018 Daniel Esteban Cardona Rojas. All rights reserved. | |
// | |
import UIKit | |
protocol ProfileInputDelegate: class { | |
func didTapEdit(_ input: ProfileInputField) | |
func didTapSave(_ input: ProfileInputField) | |
} | |
class ProfileInputField: UIView { | |
// MARK: - UI components, lazy instantiation | |
lazy var titleLabel: UILabel = { | |
let label = UILabel() | |
let titleLabelFont = UIFont.systemFont(ofSize: 14) | |
label.textAlignment = NSTextAlignment.left | |
label.font = titleLabelFont | |
label.translatesAutoresizingMaskIntoConstraints = false | |
label.textColor = UIColor.hexStringToUIColor(hex: "#bebebe") | |
return label | |
}() | |
lazy var inputField: UITextField = { | |
let textField = UITextField() | |
textField.textAlignment = NSTextAlignment.left | |
textField.borderStyle = UITextBorderStyle.none | |
textField.sizeToFit() | |
textField.isEnabled = false | |
textField.backgroundColor = .clear | |
textField.translatesAutoresizingMaskIntoConstraints = false | |
textField.textColor = UIColor.hexStringToUIColor(hex: UIConstants.kActionTextColor) | |
return textField | |
}() | |
let editIcon: UIButton = { | |
let button = UIButton(type: UIButtonType.custom) | |
button.translatesAutoresizingMaskIntoConstraints = false | |
button.contentMode = .scaleAspectFit | |
return button | |
}() | |
// MARK: - Public API | |
weak var delegate: ProfileInputDelegate? | |
var isEditable: Bool = false { | |
didSet { | |
inputField.isEnabled = isEditable | |
editIcon.isHidden = !isEditable | |
} | |
} | |
var isPassword: Bool = false { | |
didSet { | |
inputField.isSecureTextEntry = isPassword | |
} | |
} | |
var isEditing: Bool = false { | |
didSet { | |
let image = isEditing ? UIImage(named: "checkmark") : UIImage(named: "iconEdit") | |
self.editIcon.setImage(image, for: .normal) | |
self.inputField.isEnabled = isEditing | |
} | |
} | |
public func configure(title: String, content: String) { | |
titleLabel.text = title | |
inputField.text = content | |
isEditing = false | |
} | |
// MARK: - Overrides | |
override init(frame: CGRect) { | |
super.init(frame: frame) | |
self.commonInit() | |
} | |
required init?(coder aDecoder: NSCoder) { | |
super.init(coder: aDecoder) | |
self.commonInit() | |
} | |
override var intrinsicContentSize: CGSize { | |
return CGSize(width: 200, height: 66) | |
} | |
override func willMove(toSuperview newSuperview: UIView?) { | |
super.willMove(toSuperview: newSuperview) | |
commonInit() | |
} | |
// MARK: - Private | |
private func commonInit() { | |
translatesAutoresizingMaskIntoConstraints = false | |
setContentCompressionResistancePriority(UILayoutPriorityDefaultHigh, for: .vertical) | |
setContentCompressionResistancePriority(UILayoutPriorityDefaultLow, for: .horizontal) | |
setupViews() | |
setupContraints() | |
setupActions() | |
} | |
private func setupViews() { | |
self.addSubview(titleLabel) | |
self.addSubview(inputField) | |
self.addSubview(editIcon) | |
} | |
private func setupActions() { | |
self.editIcon.addTarget(self, action: #selector(didTapEditButton(_:)), for: .touchUpInside) | |
} | |
// MARK: - Actions | |
@objc func didTapEditButton(_ sender: Any) { | |
self.editIcon.setImage(nil, for: .normal) | |
isEditing = !isEditing | |
if isEditing { | |
self.inputField.becomeFirstResponder() | |
self.delegate?.didTapEdit(self) | |
} else { | |
if self.inputField.isFirstResponder { | |
self.inputField.resignFirstResponder() | |
} | |
self.delegate?.didTapSave(self) | |
} | |
} | |
// MARK: Contraints | |
private func setupContraints() { | |
setupTitleLabelConstraints() | |
setupTextFieldConstraints() | |
setupEditIconConstraints() | |
} | |
private func setupTitleLabelConstraints() { | |
NSLayoutConstraint.activate([ | |
titleLabel.leadingAnchor.constraint(equalTo: self.leadingAnchor), | |
titleLabel.topAnchor.constraint(equalTo: self.topAnchor, constant: 10), | |
titleLabel.heightAnchor.constraint(greaterThanOrEqualToConstant: 20), | |
titleLabel.trailingAnchor.constraint(equalTo: editIcon.leadingAnchor, constant: -10) | |
]) | |
} | |
private func setupTextFieldConstraints() { | |
NSLayoutConstraint.activate([ | |
inputField.leadingAnchor.constraint(equalTo: self.leadingAnchor), | |
inputField.topAnchor.constraint(greaterThanOrEqualTo: titleLabel.bottomAnchor, constant: 10), | |
inputField.widthAnchor.constraint(equalTo: titleLabel.widthAnchor), | |
inputField.heightAnchor.constraint(greaterThanOrEqualToConstant: 20), | |
inputField.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -10) | |
]) | |
} | |
private func setupEditIconConstraints() { | |
NSLayoutConstraint.activate([ | |
editIcon.leadingAnchor.constraint(equalTo: inputField.trailingAnchor, constant: 20), | |
editIcon.trailingAnchor.constraint(equalTo: self.trailingAnchor), | |
editIcon.centerYAnchor.constraint(equalTo: self.centerYAnchor), | |
editIcon.widthAnchor.constraint(equalTo: editIcon.heightAnchor), | |
editIcon.heightAnchor.constraint(equalTo: self.heightAnchor, multiplier: 0.3) | |
]) | |
} | |
} | |
extension ProfileInputField: UITextFieldDelegate { | |
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { | |
log.debug("ShouldChangeTextfield") | |
return true | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment