Skip to content

Instantly share code, notes, and snippets.

@tornikegomareli
Last active June 19, 2023 08:28
Show Gist options
  • Save tornikegomareli/8418a4978eecaec65ec74f363509923b to your computer and use it in GitHub Desktop.
Save tornikegomareli/8418a4978eecaec65ec74f363509923b to your computer and use it in GitHub Desktop.
TNETAmountTextFieldView
//
// TNETDebtView.swift
//
//
// Created by Tornike on 15/06/2023.
//
import Foundation
import UIKit
import Domain
import DesignSystem
public class TNETAmountTextFieldView: UIView {
public typealias OnValueChange = ((CGFloat) -> Void)
private var debtAmount: UtilityPayments.Template.AmountInfo?
// MARK: Views
private lazy var wrapperView: UIView = {
let view = UIView(frame: .zero)
view.backgroundColor = .white
return view
}()
private lazy var rightGrayView: UIView = {
let view = UIView(frame: .zero)
view.backgroundColor = UIColor[.gray7]
return view
}()
private lazy var textField: UITextField = {
let view = UITextField(frame: .zero)
view.font = .buttonBold
view.textColor = UIColor[.text1]
view.textAlignment = .center
view.delegate = self
view.text = "0"
view.keyboardType = .decimalPad
return view
}()
private lazy var debtLabel: UILabel = {
var view = UILabel(frame: .zero)
view.font = .tbcx(size: 10.0, weight: .regular, relativeTo: .body)
view.numberOfLines = 1
view.minimumScaleFactor = 0.9
view.textAlignment = .center
view.adjustsFontSizeToFitWidth = true
return view
}()
public var onValueChanged: OnValueChange?
override public init(frame: CGRect) {
super.init(frame: frame)
setup()
bind()
layout()
}
@available(*, unavailable)
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
public override func layoutSublayers(of layer: CALayer) {
super.layoutSublayers(of: layer)
wrapperView.layer.borderColor = UIColor[.gray3].cgColor
wrapperView.layer.borderWidth = 1
wrapperView.apply(cornerRadius: .fixed(corners: .allCorners, value: 8.0))
}
public func clearDebt(force: Bool) {
guard let debtInfo = debtAmount, debtInfo.isDebt else {
return
}
let debtValue = debtInfo.asDouble
guard debtValue != 0 else {
return
}
if textField.text?.doubleValue ?? 0.0 > 0 && !force {
return
}
textField.text = debtInfo.debt
debtTextFieldDidUpdate(with: debtInfo.debt)
}
public func resetDebt() {
let value: CGFloat = debtAmount?.asDouble ?? 0.00
updateDebt(with: value)
textField.text = ""
}
public func setDebt(amountInfo: UtilityPayments.Template.AmountInfo) {
debtAmount = amountInfo
debtLabel.text = "\(amountInfo.displayText)₾"
configureDebtLabel(amountInfoType: amountInfo.amountType)
}
private func setup() {
addSubview(wrapperView)
wrapperView.addSubview(textField)
wrapperView.addSubview(rightGrayView)
rightGrayView.addSubview(debtLabel)
}
private func bind() {
textField.addTarget(self, action: #selector(textFieldDidChange(_:)), for: .editingChanged)
setupRightViewGestureRecognizer()
}
private func layout() {
wrapperView.snp.remakeConstraints { make in
make.edges.equalToSuperview()
}
textField.snp.remakeConstraints { make in
make.leading.equalToSuperview().offset(CGFloat.spacing8)
make.top.equalToSuperview()
make.bottom.equalToSuperview()
make.trailing.equalTo(rightGrayView.snp.leading).offset(-CGFloat.spacing8)
}
rightGrayView.snp.remakeConstraints { make in
make.top.bottom.trailing.equalToSuperview()
make.width.equalTo(65.0.scaledWidth)
}
debtLabel.snp.remakeConstraints { make in
make.top.leading.equalTo(4.0)
make.bottom.trailing.equalTo(-4.0)
}
}
private func setupRightViewGestureRecognizer() {
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(debtGreyViewDidTap))
rightGrayView.addGestureRecognizer(tapGestureRecognizer)
}
private func configureDebtLabel(amountInfoType: UtilityPayments.Template.AmountInfo.AmountType) {
switch amountInfoType {
case .negative:
debtLabel.textColor = UIColor[.error]
case .positive:
debtLabel.textColor = UIColor[.success]
case .zero:
debtLabel.textColor = UIColor[.text1]
}
}
private func updateDebt(with newAmount: CGFloat) {
debtLabel.text = "\(newAmount)₾"
}
private func debtTextFieldDidUpdate(with value: String) {
let amountWithoutCurrency = value.isEmpty ? "0" : value
guard let amountInfo = debtAmount else {
return
}
guard let amountValue = amountWithoutCurrency.doubleValue else {
resetDebt()
return
}
var newUpdatedDebt: Double = amountInfo.asDouble - amountValue
if newUpdatedDebt != .zero {
newUpdatedDebt *= -1.0
}
let formatted: Double = newUpdatedDebt.roundToDecimal(2)
dump(formatted)
updateDebt(with: formatted)
configureDebtLabel(
amountInfoType: UtilityPayments.Template.AmountInfo.getAmountType(by: newUpdatedDebt)
)
onValueChanged?(formatted)
}
@objc private func debtGreyViewDidTap() {
clearDebt(force: true)
}
@objc private func textFieldDidChange(_ textField: UITextField) {
let textFieldValue = textField.text ?? ""
debtTextFieldDidUpdate(with: textFieldValue)
}
}
extension TNETAmountTextFieldView: UITextFieldDelegate {
public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
var currentText = textField.text ?? ""
var replacementString = string
replacementString = replacementString.replaceCommaWithDot()
currentText = currentText.replaceCommaWithDot()
textField.text = currentText
return true
}
}
extension Double {
func roundToDecimal(_ fractionDigits: Int) -> Double {
let multiplier = pow(10, Double(fractionDigits))
return Darwin.round(self * multiplier) / multiplier
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment