TSChatInputFullScreenVC.swift 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. //
  2. // TSChatInputFullScreenVC.swift
  3. // AIEmoji
  4. //
  5. // Created by 100Years on 2025/2/14.
  6. //
  7. import UIKit
  8. class TSChatInputFullScreenVC: TSBaseVC, UITextViewDelegate {
  9. var sendComplete:(([Any])->Void)?
  10. var closeComplete:((String)->Void)?
  11. var text:String?
  12. //AI是否正在回答问题
  13. var isAIAnswering:Bool = false{
  14. didSet{
  15. sendEnabled(enabled: !isAIAnswering)
  16. }
  17. }
  18. lazy var InputBarView:UIView = {
  19. let InputBarView = UIView()
  20. InputBarView.backgroundColor = "#222222".uiColor
  21. InputBarView.cornerRadius = 28.0
  22. return InputBarView
  23. }()
  24. lazy var sendBtn: UIButton = {
  25. let sendBtn = UIButton.createButton(image: UIImage(named: "chat_send")) { [weak self] in
  26. guard let self = self else { return }
  27. sendMsg()
  28. }
  29. return sendBtn
  30. }()
  31. lazy var minificationBtn: UIButton = {
  32. let minificationBtn = UIButton.createButton(image: UIImage(named: "chat_send_minify")) { [weak self] in
  33. guard let self = self else { return }
  34. closeComplete?(textView.text)
  35. self.dismiss(animated: true)
  36. }
  37. return minificationBtn
  38. }()
  39. private let minHeight: CGFloat = 24
  40. private let maxHeight: CGFloat = 154
  41. lazy var textView: TSCustomTextView = {
  42. let textView = TSCustomTextView()
  43. textView.backgroundColor = .clear
  44. textView.textColor = .white
  45. textView.delegate = self
  46. textView.font = .font(size: 16)
  47. textView.clipsToBounds = true
  48. textView.isScrollEnabled = false
  49. textView.tintColor = .themeColor
  50. textView.returnKeyType = .send
  51. textView.placeholder = "Type all necessary details".localized
  52. textView.placeholderColor = .white.withAlphaComponent(0.4)
  53. textView.placeholderLabel.font = .font(size: 16.0)
  54. textView.textInsets = UIEdgeInsets(top: 5, left: 0, bottom: 5, right: 0)
  55. return textView
  56. }()
  57. override func createView() {
  58. setNavBarViewHidden(true)
  59. edgesForExtendedLayout = []
  60. contentView.addSubview(InputBarView)
  61. InputBarView.addSubview(textView)
  62. InputBarView.addSubview(minificationBtn)
  63. InputBarView.addSubview(sendBtn)
  64. InputBarView.snp.makeConstraints { make in
  65. make.leading.equalTo(16)
  66. make.trailing.equalTo(-16)
  67. make.top.equalTo(12+k_Height_NavBar)
  68. make.bottom.equalTo(-12-k_Height_safeAreaInsetsBottom())
  69. }
  70. textView.snp.makeConstraints { make in
  71. make.leading.equalTo(16)
  72. make.trailing.equalTo(-60)
  73. make.top.equalTo(16)
  74. make.bottom.equalTo(-16)
  75. make.height.equalTo(minHeight)
  76. }
  77. sendBtn.snp.makeConstraints { make in
  78. make.trailing.equalTo(-16)
  79. make.bottom.equalTo(-16)
  80. make.width.equalTo(24)
  81. make.height.equalTo(24)
  82. }
  83. minificationBtn.snp.makeConstraints { make in
  84. make.trailing.equalTo(-16)
  85. make.top.equalTo(16)
  86. make.width.equalTo(24)
  87. make.height.equalTo(24)
  88. }
  89. }
  90. override func dealThings() {
  91. textView.text = text
  92. let tapGesture = UITapGestureRecognizer(target: self, action: #selector(clickView))
  93. tapGesture.cancelsTouchesInView = false
  94. InputBarView.addGestureRecognizer(tapGesture)
  95. // 监听文本变化事件
  96. NotificationCenter.default.addObserver(self, selector: #selector(textDidChange), name: UITextView.textDidChangeNotification, object: textView)
  97. // 监听键盘事件
  98. NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil)
  99. NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: UIResponder.keyboardWillHideNotification, object: nil)
  100. NotificationCenter.default.addObserver(self, selector: #selector(handleAIAnsweringNotification(_:)), name: .kAIAnsweringNotification, object: nil)
  101. }
  102. @objc func clickView(){
  103. view.endEditing(true)
  104. }
  105. @objc private func textDidChange() {
  106. sendEnabled(enabled: textView.text.count > 0)
  107. }
  108. func sendMsg(){
  109. if sendBtn.isEnabled == false {
  110. return
  111. }
  112. // if textView.text.replacingOccurrences(of: " ", with: "").count <= 0 {
  113. // return
  114. // }
  115. if let string = textView.text {
  116. sendComplete?([string])
  117. textView.resignFirstResponder()
  118. dismiss(animated: true)
  119. }
  120. }
  121. func sendEnabled(enabled:Bool){
  122. if enabled == true,
  123. isAIAnswering == false,
  124. textView.text.replacingOccurrences(of: " ", with: "").count > 0 {
  125. sendBtn.isEnabled = true
  126. }else{
  127. sendBtn.isEnabled = false
  128. }
  129. }
  130. @objc func keyboardWillShow(_ notification: Notification) {
  131. guard let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect,
  132. let animationDuration = notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? TimeInterval else {
  133. return
  134. }
  135. let keyboardHeight = keyboardFrame.height
  136. let contentInset = UIEdgeInsets(top: 0, left: 0, bottom: keyboardHeight, right: 0)
  137. UIView.animate(withDuration: animationDuration) {
  138. self.textView.contentInset = contentInset
  139. self.textView.scrollIndicatorInsets = contentInset
  140. }
  141. UIView.animate(withDuration: animationDuration+0.8) {
  142. self.sendBtn.snp.updateConstraints { make in
  143. make.bottom.equalTo(-keyboardHeight + k_Height_safeAreaInsetsBottom())
  144. }
  145. }
  146. }
  147. @objc func keyboardWillHide(_ notification: Notification) {
  148. guard let animationDuration = notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? TimeInterval else {
  149. return
  150. }
  151. let contentInset = UIEdgeInsets.zero
  152. UIView.animate(withDuration: animationDuration) {
  153. self.textView.contentInset = contentInset
  154. self.textView.scrollIndicatorInsets = contentInset
  155. self.sendBtn.snp.updateConstraints { make in
  156. make.bottom.equalTo(-16)
  157. }
  158. }
  159. }
  160. @objc func handleAIAnsweringNotification(_ notification: Notification) {
  161. if let userInfo = notification.userInfo, let boolValue = userInfo[kIsAIAnswering] as? Bool {
  162. isAIAnswering = boolValue
  163. }
  164. }
  165. deinit {
  166. // 移除通知监听
  167. NotificationCenter.default.removeObserver(self)
  168. }
  169. }
  170. extension TSChatInputFullScreenVC {
  171. // 实现 UITextViewDelegate 协议方法,控制 return 键行为
  172. func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
  173. if text == "\n" {
  174. // 当输入为换行符(即按下 return 键)时,执行相应操作
  175. sendMsg()
  176. return false
  177. }
  178. return true
  179. }
  180. }