LNCommonTextView.swift 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. //
  2. // LNCommonTextView.swift
  3. // Lanu
  4. //
  5. // Created by OneeChan on 2025/12/23.
  6. //
  7. import Foundation
  8. import UIKit
  9. import SnapKit
  10. class LNCommonTextView: UIView {
  11. var maxInput = 0 {
  12. didSet {
  13. textViewDidChange(textView)
  14. textLengthLabel.isHidden = maxInput == 0
  15. }
  16. }
  17. let placeholderLabel = UILabel()
  18. let textView = UITextView()
  19. var text: String {
  20. textView.text
  21. }
  22. var attrText: NSTextStorage {
  23. textView.textStorage
  24. }
  25. private let textLengthLabel = UILabel()
  26. weak var delegate: UITextViewDelegate?
  27. override init(frame: CGRect) {
  28. super.init(frame: frame)
  29. setupViews()
  30. }
  31. func setText(_ text: String) {
  32. textView.text = text
  33. textViewDidChange(textView)
  34. }
  35. required init?(coder: NSCoder) {
  36. fatalError("init(coder:) has not been implemented")
  37. }
  38. }
  39. extension LNCommonTextView: UITextViewDelegate {
  40. func textViewDidChange(_ textView: UITextView) {
  41. placeholderLabel.isHidden = !textView.text.isEmpty
  42. textLengthLabel.text = "\(textView.text.count)/\(maxInput)"
  43. delegate?.textViewDidChange?(textView)
  44. }
  45. func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
  46. let currentText = textView.text ?? ""
  47. guard let swiftRange = Range(range, in: currentText) else {
  48. return true
  49. }
  50. let newText = currentText.replacingCharacters(in: swiftRange, with: text)
  51. if maxInput > 0, newText.count > maxInput {
  52. return false
  53. }
  54. return delegate?.textView?(textView, shouldChangeTextIn: range, replacementText: text) ?? true
  55. }
  56. }
  57. extension LNCommonTextView {
  58. private func setupViews() {
  59. backgroundColor = .fill_1
  60. layer.cornerRadius = 12
  61. textLengthLabel.isHidden = true
  62. textLengthLabel.text = "0/\(maxInput)"
  63. textLengthLabel.font = .body_m
  64. textLengthLabel.textColor = .text_2
  65. addSubview(textLengthLabel)
  66. textLengthLabel.snp.makeConstraints { make in
  67. make.trailing.equalToSuperview().offset(-12)
  68. make.bottom.equalToSuperview().offset(-12)
  69. }
  70. placeholderLabel.text = .init(key: "A00006")
  71. placeholderLabel.font = .body_m
  72. placeholderLabel.textColor = .text_3
  73. placeholderLabel.numberOfLines = 0
  74. addSubview(placeholderLabel)
  75. placeholderLabel.snp.makeConstraints { make in
  76. make.horizontalEdges.equalToSuperview().inset(12)
  77. make.top.equalToSuperview().offset(12)
  78. }
  79. textView.font = .body_m
  80. textView.textColor = .text_5
  81. textView.backgroundColor = .clear
  82. textView.delegate = self
  83. textView.visibleView = self
  84. addSubview(textView)
  85. textView.snp.makeConstraints { make in
  86. make.horizontalEdges.equalToSuperview().inset(12 - 4)
  87. make.top.equalToSuperview().offset(12 - 7)
  88. make.bottom.equalTo(textLengthLabel.snp.top)
  89. }
  90. }
  91. }