MCProxyTextViewRx.swift 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. //
  2. // MCProxyTextViewRx.swift
  3. // HCQuanfangtong
  4. //
  5. // Created by Apple on 2022/4/11.
  6. // Copyright © 2022 Jyp. All rights reserved.
  7. //
  8. import Foundation
  9. import RxSwift
  10. import RxCocoa
  11. /// 自动注入
  12. @propertyWrapper class TextViewWrapper{
  13. var defaultValue : UITextView?
  14. /// 字数限制label
  15. weak var limitLabel : UILabel?
  16. /// 最大长度
  17. var maxLength : Int
  18. /// 输入结束事件
  19. var endBlock : ()->Void
  20. let disposeAutoRelease = DisposeBag()
  21. var wrappedValue : UITextView?{
  22. didSet{
  23. wrappedValue?.rx.bindDelegate(delegate: MCTextViewDelegate.init(maxLength: maxLength, limitLabel: limitLabel, endBlock: endBlock)).subscribe().disposed(by: disposeAutoRelease)
  24. }
  25. }
  26. init(wrappedValue defaultValue: UITextView? = nil, maxLength: Int, limitLabel: UILabel? = nil, endBlock: @escaping ()->Void){
  27. self.defaultValue = defaultValue
  28. self.maxLength = maxLength
  29. self.limitLabel = limitLabel
  30. self.endBlock = endBlock
  31. }
  32. }
  33. class MCTextViewDelegate : NSObject, UITextViewDelegate{
  34. /// 最大长度
  35. var maxLength : Int
  36. /// 字数限制label
  37. weak var limitLabel : UILabel?
  38. /// 输入结束事件
  39. var endBlock : ()->Void
  40. func textViewDidChangeSelection(_ textView: UITextView) {
  41. let toBeString = textView.text;
  42. let lang = textView.textInputMode?.primaryLanguage
  43. if lang == "zh-Hans"{
  44. let textRange = textView.markedTextRange
  45. if let range = textRange{
  46. if textView.position(from: range.start, offset: 0) != nil{
  47. return
  48. }
  49. }
  50. }
  51. if toBeString?.count ?? 0 > maxLength{
  52. let text = toBeString?.prefix(maxLength)
  53. textView.text = String(text ?? "")
  54. }
  55. limitLabel?.text = "\(textView.text.count)/\(maxLength)"
  56. }
  57. func textViewDidEndEditing(_ textView: UITextView){
  58. self.endBlock()
  59. }
  60. init(maxLength: Int, limitLabel: UILabel? = nil, endBlock: @escaping ()->Void) {
  61. self.maxLength = maxLength
  62. self.limitLabel = limitLabel
  63. self.endBlock = endBlock
  64. }
  65. }
  66. extension Reactive where Base:UITextView{
  67. var textDelegate : DelegateProxy<UITextView, UITextViewDelegate>{
  68. return TextViewDelegateProxy.proxy(for: base)
  69. }
  70. func bindDelegate(delegate:UITextViewDelegate)->RxSwift.Observable<[Any]>{
  71. self.base.delegate = delegate
  72. return textDelegate.methodInvoked(#selector(UITextViewDelegate.textViewDidChangeSelection(_:)))
  73. }
  74. }
  75. public class TextViewDelegateProxy : DelegateProxy<UITextView, UITextViewDelegate>,UITextViewDelegate,DelegateProxyType{
  76. public weak private(set) var textView : UITextView?
  77. init(textView: UITextView) {
  78. self.textView = textView
  79. super.init(parentObject: textView, delegateProxy: TextViewDelegateProxy.self)
  80. }
  81. public static func registerKnownImplementations() {
  82. self.register {
  83. TextViewDelegateProxy.init(textView: $0)
  84. }
  85. }
  86. public static func currentDelegate(for object: UITextView) -> UITextViewDelegate? {
  87. return object.delegate
  88. }
  89. public static func setCurrentDelegate(_ delegate: UITextViewDelegate?, to object: UITextView) {
  90. object.delegate = delegate
  91. }
  92. public override func setForwardToDelegate(_ delegate: DelegateProxy<UITextView, UITextViewDelegate>.Delegate?, retainDelegate: Bool) {
  93. super.setForwardToDelegate(delegate, retainDelegate: true)
  94. }
  95. }