LNCommonInputPanel.swift 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. //
  2. // LNCommonInputPanel.swift
  3. // Gami
  4. //
  5. // Created by OneeChan on 2026/3/3.
  6. //
  7. import Foundation
  8. import UIKit
  9. import SnapKit
  10. class LNCommonInputPanel: LNPopupView {
  11. var maxInput = 0
  12. private let textView = LNAutoSizeTextView()
  13. private var hideSend: Constraint?
  14. private let sendView = UIView()
  15. var handler: ((String) -> Void)?
  16. override init(frame: CGRect) {
  17. super.init(frame: frame)
  18. setupViews()
  19. }
  20. override func popup(_ targetView: UIView? = nil, animated: Bool = true) {
  21. super.popup(targetView, animated: animated)
  22. textView.becomeFirstResponder()
  23. }
  24. required init?(coder: NSCoder) {
  25. fatalError("init(coder:) has not been implemented")
  26. }
  27. }
  28. extension LNCommonInputPanel {
  29. private func toSendText() {
  30. dismiss()
  31. let cleanedText = (textView.text ?? "").replacingOccurrences(of: "\n", with: "").trimmingCharacters(in: .whitespacesAndNewlines)
  32. guard !cleanedText.isEmpty else { return }
  33. handler?(cleanedText)
  34. }
  35. }
  36. extension LNCommonInputPanel: UITextViewDelegate {
  37. func textViewDidChange(_ textView: UITextView) {
  38. if maxInput > 0, textView.text.count > maxInput {
  39. textView.text = String(textView.text.prefix(maxInput))
  40. }
  41. let showSend = !textView.text.isEmpty
  42. hideSend?.update(priority: showSend ? .low : .high)
  43. UIView.animate(withDuration: 0.2) { [weak self] in
  44. guard let self else { return }
  45. layoutIfNeeded()
  46. }
  47. }
  48. func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
  49. if text == "\n" {
  50. toSendText()
  51. return false
  52. }
  53. if maxInput > 0 {
  54. let currentText = textView.text ?? ""
  55. guard let swiftRange = Range(range, in: currentText) else {
  56. return true
  57. }
  58. let newText = currentText.replacingCharacters(in: swiftRange, with: text)
  59. if newText.count > maxInput {
  60. return false
  61. }
  62. }
  63. return true
  64. }
  65. }
  66. extension LNCommonInputPanel {
  67. private func setupViews() {
  68. container.layer.cornerRadius = 0
  69. ignoreKeyboardToDismiss = true
  70. let inputContainer = UIView()
  71. container.addSubview(inputContainer)
  72. inputContainer.snp.makeConstraints { make in
  73. make.horizontalEdges.equalToSuperview()
  74. make.top.equalToSuperview().offset(10)
  75. make.bottom.equalToSuperview().offset(-5 + commonBottomInset)
  76. }
  77. let holder = UIView()
  78. holder.backgroundColor = .fill_2
  79. holder.layer.cornerRadius = 19
  80. holder.snp.makeConstraints { make in
  81. make.height.greaterThanOrEqualTo(38)
  82. }
  83. inputContainer.addSubview(holder)
  84. holder.snp.makeConstraints { make in
  85. make.verticalEdges.equalToSuperview()
  86. make.leading.equalToSuperview().offset(12)
  87. hideSend = make.trailing.equalToSuperview().offset(-12).priority(.high).constraint
  88. }
  89. textView.backgroundColor = .clear
  90. textView.delegate = self
  91. textView.font = .body_m
  92. textView.textColor = .text_5
  93. textView.returnKeyType = .send
  94. holder.addSubview(textView)
  95. textView.snp.makeConstraints { make in
  96. make.horizontalEdges.equalToSuperview().inset(10)
  97. make.centerY.equalToSuperview()
  98. make.top.greaterThanOrEqualToSuperview()
  99. }
  100. inputContainer.addSubview(sendView)
  101. sendView.snp.makeConstraints { make in
  102. make.leading.equalTo(holder.snp.trailing).offset(12)
  103. make.trailing.equalToSuperview().offset(-12).priority(.medium)
  104. make.bottom.equalToSuperview()
  105. }
  106. let sendButton = UIButton()
  107. sendButton.layer.cornerRadius = 16
  108. sendButton.clipsToBounds = true
  109. sendButton.setTitle(.init(key: "A00305"), for: .normal)
  110. sendButton.setTitleColor(.text_1, for: .normal)
  111. sendButton.titleLabel?.font = .heading_h4
  112. sendButton.setBackgroundImage(.primary_8, for: .normal)
  113. sendButton.contentEdgeInsets = .init(top: 0, left: 16, bottom: 0, right: 16)
  114. sendButton.addAction(UIAction(handler: { [weak self] _ in
  115. guard let self else { return }
  116. toSendText()
  117. }), for: .touchUpInside)
  118. sendView.addSubview(sendButton)
  119. sendButton.snp.makeConstraints { make in
  120. make.height.equalTo(32)
  121. make.horizontalEdges.equalToSuperview()
  122. make.bottom.equalToSuperview().offset(-2)
  123. make.top.equalToSuperview()
  124. }
  125. }
  126. }