TextFieldTableViewCell.swift 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. //
  2. // TextFieldTableViewCell.swift
  3. // Naterade
  4. //
  5. // Created by Nathan Racklyeft on 5/22/16.
  6. // Copyright © 2016 Nathan Racklyeft. All rights reserved.
  7. //
  8. import UIKit
  9. public protocol TextFieldTableViewCellDelegate: AnyObject {
  10. func textFieldTableViewCellDidBeginEditing(_ cell: TextFieldTableViewCell)
  11. func textFieldTableViewCellDidEndEditing(_ cell: TextFieldTableViewCell)
  12. func textFieldTableViewCellDidChangeEditing(_ cell: TextFieldTableViewCell)
  13. }
  14. // MARK: - Default Implementations
  15. extension TextFieldTableViewCellDelegate {
  16. public func textFieldTableViewCellDidChangeEditing(_ cell: TextFieldTableViewCell) { }
  17. }
  18. public class TextFieldTableViewCell: UITableViewCell, UITextFieldDelegate {
  19. @IBOutlet public weak var unitLabel: UILabel? {
  20. didSet {
  21. // Setting this color in code because the nib isn't being applied correctly
  22. unitLabel?.textColor = .secondaryLabel
  23. }
  24. }
  25. @IBOutlet public weak var textField: UITextField! {
  26. didSet {
  27. textField.delegate = self
  28. textField.addTarget(self, action: #selector(textFieldEditingChanged), for: .editingChanged)
  29. // Setting this color in code because the nib isn't being applied correctly
  30. textField.textColor = .label
  31. }
  32. }
  33. public var maximumTextLength: Int?
  34. override public func prepareForReuse() {
  35. super.prepareForReuse()
  36. textField.delegate = nil
  37. unitLabel?.text = nil
  38. }
  39. public weak var delegate: TextFieldTableViewCellDelegate?
  40. @objc private func textFieldEditingChanged() {
  41. delegate?.textFieldTableViewCellDidChangeEditing(self)
  42. }
  43. // MARK: - UITextFieldDelegate
  44. public func textFieldDidBeginEditing(_ textField: UITextField) {
  45. // Even though we are likely already on .main, we still need to queue this cursor (selection) change in
  46. // order for it to work
  47. DispatchQueue.main.async { [weak self] in
  48. guard let self = self else { return }
  49. self.textField.moveCursorToEnd()
  50. self.delegate?.textFieldTableViewCellDidBeginEditing(self)
  51. }
  52. }
  53. public func textFieldDidEndEditing(_ textField: UITextField) {
  54. delegate?.textFieldTableViewCellDidEndEditing(self)
  55. }
  56. public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
  57. guard let maximumTextLength = maximumTextLength else {
  58. return true
  59. }
  60. let text = textField.text ?? ""
  61. let allText = (text as NSString).replacingCharacters(in: range, with: string)
  62. if allText.count <= maximumTextLength {
  63. return true
  64. } else {
  65. textField.text = String(allText.prefix(maximumTextLength))
  66. return false
  67. }
  68. }
  69. }