LNIMChatUserRemarkPanel.swift 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. //
  2. // LNIMChatUserRemarkPanel.swift
  3. // Gami
  4. //
  5. // Created by OneeChan on 2026/2/8.
  6. //
  7. import Foundation
  8. import UIKit
  9. import SnapKit
  10. class LNIMChatUserRemarkPanel: LNPopupView {
  11. private let countLabel = UILabel()
  12. private let inputField = UITextField()
  13. private let confirmButton = UIButton()
  14. var handler: ((String) -> Void)?
  15. override init(frame: CGRect) {
  16. super.init(frame: frame)
  17. setupViews()
  18. }
  19. func update(_ remark: String) {
  20. inputField.text = remark
  21. updateCount()
  22. }
  23. required init?(coder: NSCoder) {
  24. fatalError("init(coder:) has not been implemented")
  25. }
  26. }
  27. extension LNIMChatUserRemarkPanel: UITextFieldDelegate {
  28. func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
  29. let currentText = textField.text ?? ""
  30. guard let range = Range(range, in: currentText) else { return false }
  31. let newText = currentText.replacingCharacters(in: range, with: string)
  32. if newText.count < currentText.count {
  33. return true
  34. }
  35. return newText.count <= LNIMManager.maxRemarkLength
  36. }
  37. func textFieldShouldReturn(_ textField: UITextField) -> Bool {
  38. textField.resignFirstResponder()
  39. return true
  40. }
  41. }
  42. extension LNIMChatUserRemarkPanel {
  43. private func updateCount() {
  44. let count = inputField.text?.count ?? 0
  45. countLabel.text = "\(count)/\(LNIMManager.maxRemarkLength)"
  46. }
  47. private func setupViews() {
  48. let header = buildHeader()
  49. container.addSubview(header)
  50. header.snp.makeConstraints { make in
  51. make.horizontalEdges.equalToSuperview()
  52. make.top.equalToSuperview()
  53. }
  54. let tipsLabel = UILabel()
  55. tipsLabel.font = .heading_h4
  56. tipsLabel.text = .init(key: "A00290")
  57. tipsLabel.textColor = .text_5
  58. container.addSubview(tipsLabel)
  59. tipsLabel.snp.makeConstraints { make in
  60. make.leading.equalToSuperview().offset(16)
  61. make.top.equalTo(header.snp.bottom)
  62. }
  63. updateCount()
  64. countLabel.font = .body_m
  65. countLabel.textColor = .text_5
  66. container.addSubview(countLabel)
  67. countLabel.snp.makeConstraints { make in
  68. make.trailing.equalToSuperview().offset(-16)
  69. make.centerY.equalTo(tipsLabel)
  70. }
  71. let inputHolder = UIView()
  72. inputHolder.backgroundColor = .fill_1
  73. inputHolder.layer.cornerRadius = 8
  74. container.addSubview(inputHolder)
  75. inputHolder.snp.makeConstraints { make in
  76. make.top.equalTo(tipsLabel.snp.bottom).offset(8)
  77. make.horizontalEdges.equalToSuperview().inset(16)
  78. make.height.equalTo(46)
  79. }
  80. inputField.font = .body_m
  81. inputField.textColor = .text_5
  82. inputField.clearButtonMode = .whileEditing
  83. inputField.delegate = self
  84. inputField.returnKeyType = .done
  85. inputField.visibleView = inputHolder
  86. inputField.placeholder = .init(key: "A00006")
  87. inputField.addAction(UIAction(handler: { [weak self] _ in
  88. guard let self else { return }
  89. updateCount()
  90. }), for: .editingChanged)
  91. inputHolder.addSubview(inputField)
  92. inputField.snp.makeConstraints { make in
  93. make.horizontalEdges.equalToSuperview().inset(12)
  94. make.centerY.equalToSuperview()
  95. }
  96. confirmButton.setTitle(.init(key: "A00185"), for: .normal)
  97. confirmButton.setTitleColor(.text_1, for: .normal)
  98. confirmButton.titleLabel?.font = .heading_h3
  99. confirmButton.setBackgroundImage(.primary_8, for: .normal)
  100. confirmButton.layer.cornerRadius = 23.5
  101. confirmButton.clipsToBounds = true
  102. confirmButton.backgroundColor = .fill_4
  103. confirmButton.addAction(UIAction(handler: { [weak self] _ in
  104. guard let self else { return }
  105. guard let text = inputField.text else { return }
  106. dismiss()
  107. handler?(text)
  108. }), for: .touchUpInside)
  109. container.addSubview(confirmButton)
  110. confirmButton.snp.makeConstraints { make in
  111. make.horizontalEdges.equalToSuperview().inset(12)
  112. make.top.equalTo(inputHolder.snp.bottom).offset(66)
  113. make.bottom.equalToSuperview().offset(commonBottomInset)
  114. make.height.equalTo(47)
  115. }
  116. }
  117. private func buildHeader() -> UIView {
  118. let container = UIView()
  119. container.snp.makeConstraints { make in
  120. make.height.equalTo(50)
  121. }
  122. let titleLabel = UILabel()
  123. titleLabel.font = .heading_h3
  124. titleLabel.textColor = .text_5
  125. titleLabel.text = .init(key: "A00086")
  126. container.addSubview(titleLabel)
  127. titleLabel.snp.makeConstraints { make in
  128. make.center.equalToSuperview()
  129. }
  130. return container
  131. }
  132. }