ElementUtil.swift 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446
  1. //
  2. // ElementUtil.swift
  3. // HCQuanfangtong
  4. //
  5. // Created by Apple on 2022/3/25.
  6. // Copyright © 2022 Jyp. All rights reserved.
  7. //
  8. import Foundation
  9. import RxSwift
  10. import RxCocoa
  11. import UIKit
  12. /// Element相关工具
  13. //MARK: - 输入控制 InputControl
  14. extension UITextField{
  15. // @TextFieldPhoneWrapper(block: {
  16. //
  17. // })
  18. // @TextFieldOtherWrapper(type: .text, maxLength: 10, block:{
  19. //
  20. // })
  21. // @TextFieldDecimalWrapper(maxValue: 100, block: {
  22. //
  23. // })
  24. // @TextFieldWrapper(type:.decimal, maxLength: 9, decimalLength:2, endBlock:{
  25. //
  26. // })
  27. // @TextFieldDegitalWrapper(maxLength: 9, maxValue: 100, block: {
  28. //
  29. // })
  30. // var textField : UITextField?
  31. /// 9 + 2 小数限制
  32. /// - Parameters:
  33. /// - element: <#element description#>
  34. /// - maxValue: <#maxValue description#>
  35. /// - block: <#block description#>
  36. public func inputDecimal(maxValue: Float? = nil, checkBlock: (()->Bool)? = nil, block: @escaping (()->Void)){
  37. self.keyboardType = UIKeyboardType.decimalPad
  38. _ = self.rx.bindDelegate(delegate: MCTextFieldDelegate.decimalDefault(maxValue: maxValue, checkBlock: checkBlock, block: block)).takeUntil(self.rx.deallocated).subscribe()
  39. }
  40. /// 电话限制
  41. /// - Parameters:
  42. /// - element: <#element description#>
  43. /// - block: <#block description#>
  44. public func inputPhone(checkBlock: (()->Bool)? = nil, block: @escaping (()->Void)){
  45. self.keyboardType = UIKeyboardType.numberPad
  46. _ = self.rx.bindDelegate(delegate: MCTextFieldDelegate.phone(checkBlock: checkBlock, block: block)).takeUntil(self.rx.deallocated).subscribe()
  47. }
  48. /// 文本长度限制
  49. /// - Parameters:
  50. /// - element: <#element description#>
  51. /// - maxLength: <#maxLength description#>
  52. /// - block: <#block description#>
  53. public func inputText(maxLength: Int? = nil, checkBlock: (()->Bool)? = nil, block: @escaping (()->Void)){
  54. self.keyboardType = UIKeyboardType.default
  55. self.bindChineseDelegate(delegate: MCTextFieldDelegate.text(maxLength: maxLength, checkBlock: checkBlock, block: block))
  56. }
  57. /// 字符长度限制 不可以输入中文
  58. /// - Parameters:
  59. /// - maxLength: <#maxLength description#>
  60. /// - block: <#block description#>
  61. public func inputCharater(maxLength: Int? = nil, checkBlock: (()->Bool)? = nil, block: @escaping (()->Void)){
  62. self.keyboardType = UIKeyboardType.asciiCapable
  63. _ = self.rx.bindDelegate(delegate: MCTextFieldDelegate.charater(maxLength: maxLength, checkBlock: checkBlock, block: block)).takeUntil(self.rx.deallocated).subscribe()
  64. }
  65. /// 整数强效验 不能0 开头
  66. /// - Parameters:
  67. /// - element: <#element description#>
  68. /// - maxLength: <#maxLength description#>
  69. /// - maxValue: <#maxValue description#>
  70. /// - block: <#block description#>
  71. public func inputDegital(maxLength: Int? = nil, maxValue: Float? = nil, checkBlock: (()->Bool)? = nil, block: @escaping (()->Void)){
  72. self.keyboardType = UIKeyboardType.numberPad
  73. _ = self.rx.bindDelegate(delegate: MCTextFieldDelegate.degital(maxLength: maxLength, maxValue: maxValue, checkBlock: checkBlock, block: block)).takeUntil(self.rx.deallocated).subscribe()
  74. }
  75. /// 整数效验
  76. /// - Parameters:
  77. /// - element: <#element description#>
  78. /// - maxLength: <#maxLength description#>
  79. /// - maxValue: <#maxValue description#>
  80. /// - block: <#block description#>
  81. public func inputNumber(maxLength: Int? = nil, maxValue: Float? = nil, checkBlock: (()->Bool)? = nil, block: @escaping (()->Void)){
  82. self.keyboardType = UIKeyboardType.numberPad
  83. _ = self.rx.bindDelegate(delegate: MCTextFieldDelegate.number(maxLength: maxLength, maxValue: maxValue, checkBlock: checkBlock, block: block)).takeUntil(self.rx.deallocated).subscribe()
  84. }
  85. /// 只可以输入数字和字母
  86. /// - Parameters:
  87. /// - maxLength: <#maxLength description#>
  88. /// - block: <#block description#>
  89. public func inputNumberOrLetter(maxLength: Int? = nil, checkBlock: (()->Bool)? = nil, block: @escaping (()->Void)){
  90. self.keyboardType = UIKeyboardType.asciiCapable
  91. _ = self.rx.bindDelegate(delegate: MCTextFieldDelegate.numberOrLetter(maxLength: maxLength, checkBlock: checkBlock, block: block)).takeUntil(self.rx.deallocated).subscribe()
  92. }
  93. /// 只可以输入中文
  94. /// - Parameters:
  95. /// - maxLength: <#maxLength description#>
  96. /// - block: <#block description#>
  97. public func inputChinese(maxLength: Int? = nil, checkBlock: (()->Bool)? = nil, block: @escaping (()->Void)){
  98. self.keyboardType = UIKeyboardType.default
  99. self.bindChineseDelegate(delegate: MCTextFieldDelegate.chinese(maxLength: maxLength, checkBlock: checkBlock, block: block))
  100. }
  101. }
  102. extension UITextView{
  103. // @TextViewWrapper(maxLength: 100, endBlock: {
  104. //
  105. // })
  106. // var textView : UITextView?
  107. @objc(inputTextWithMaxLength: limitLabel: block:)
  108. /// 输入限制
  109. /// - Parameters:
  110. /// - maxLength: 最大长度
  111. /// - limitLabel: 字数限制label
  112. /// - block: 输入完
  113. ///
  114. public func inputText(maxLength: Int, limitLabel: UILabel? = nil, block: @escaping (()->Void)){
  115. let delegate = MCTextViewDelegate.init(maxLength: maxLength, limitLabel: limitLabel, endBlock: block)
  116. _ = self.rx.bindDelegate(delegate: delegate).takeUntil(delegate.rx.deallocated).subscribe()
  117. }
  118. }
  119. //MARK: - 关联
  120. extension UIView{
  121. struct AssociatedBinderKey{
  122. static var observables = "AssociatedBinderKeyObservables"
  123. }
  124. private var associatedBinderObservables : [Disposable]?{
  125. set{
  126. objc_setAssociatedObject(self, &AssociatedBinderKey.observables, newValue, .OBJC_ASSOCIATION_COPY_NONATOMIC)
  127. }
  128. get{
  129. objc_getAssociatedObject(self, &AssociatedBinderKey.observables) as? [Disposable]
  130. }
  131. }
  132. /// 绑定
  133. /// - Parameters:
  134. /// - btns:
  135. /// - binderBtns: 被绑定的按钮数组
  136. /// - combinText: 重组文本block
  137. /// - dismantingText: 拆解文本block
  138. /// - relations: 关联关系
  139. static func binder(_ btns: [UIView], binderBtns:[UIButton], combinText: @escaping ([String]) -> String, dismantingText: @escaping (String) -> [String], relations: [String : String]? = nil, endBlock:(([String]?)->Void)? = nil){
  140. for view in btns{
  141. if let disposables = view.associatedBinderObservables{
  142. for dis in disposables{
  143. dis.dispose()
  144. }
  145. }
  146. }
  147. for btn in binderBtns{
  148. if let disposables = btn.associatedBinderObservables{
  149. for dis in disposables{
  150. dis.dispose()
  151. }
  152. }
  153. }
  154. guard btns.count > 0 , binderBtns.count > 0 else{
  155. return
  156. }
  157. var observables : [Observable<[Any]>] = []
  158. for btn in btns{
  159. if btn is UILabel{
  160. observables.append(btn.rx.methodInvoked(#selector(setter: (btn as! UILabel).text)))
  161. }
  162. else if btn is UIButton{
  163. observables.append(btn.rx.methodInvoked(#selector((btn as! UIButton).setTitle(_:for:))))
  164. }
  165. else if btn is UITextField{
  166. observables.append(btn.rx.methodInvoked(#selector(setter: (btn as! UITextField).text)))
  167. }
  168. }
  169. btns[0].associatedBinderObservables = []
  170. btns[0].associatedBinderObservables?.append(
  171. Observable.combineLatest(observables).takeUntil(btns[0].rx.deallocated).subscribe(onNext:{text in
  172. let curStr = combinText(btns.titles)
  173. if !curStr.isEmpty{
  174. var beRelationStr : String?
  175. if relations?.keys.contains(curStr) ?? false{
  176. beRelationStr = relations![curStr]
  177. }
  178. for btn in binderBtns{
  179. if btn.titleLabel?.text ?? "" == (beRelationStr ?? curStr){
  180. if !btn.isSelected{
  181. btn.isSelected = true
  182. }
  183. }
  184. else{
  185. if btn.isSelected{
  186. btn.isSelected = false
  187. }
  188. }
  189. }
  190. endBlock?(btns.titles)
  191. return
  192. }
  193. endBlock?(nil)
  194. binderBtns.isSelected(false)
  195. }))
  196. for btn in binderBtns{
  197. btn.associatedBinderObservables = []
  198. btn.associatedBinderObservables?.append(btn.rx.shareTap.takeUntil(btn.rx.deallocated).subscribe(onNext:{_ in
  199. if btn.isSelected{
  200. return
  201. }
  202. for curBtn in binderBtns{
  203. if curBtn == btn{
  204. curBtn.isSelected = true
  205. }
  206. else{
  207. curBtn.isSelected = false
  208. }
  209. }
  210. if let curStr = btn.titleLabel?.text{
  211. var relationStr : String?
  212. if relations.isNotNil{
  213. for key in relations!.keys{
  214. if relations![key] == curStr{
  215. relationStr = key
  216. break
  217. }
  218. }
  219. }
  220. let curStr = relationStr ?? curStr
  221. let btnsTitle = dismantingText(curStr)
  222. if btnsTitle.count == btns.count{
  223. for i in 0..<btnsTitle.count{
  224. let str = btnsTitle[i]
  225. let curView = btns[i]
  226. if curView is UILabel{
  227. (curView as! UILabel).text = str
  228. }
  229. else if curView is UIButton{
  230. (curView as! UIButton).setTitle(str, for: (curView as! UIButton).state)
  231. }
  232. else if curView is UITextField{
  233. (curView as! UITextField).text = str
  234. }
  235. }
  236. }
  237. }
  238. }))
  239. }
  240. }
  241. func binder(binderBtns: [UIButton], relations: [String:String]? = nil, endBlock: ((String?)->Void)? = nil, quickBtnTapBlock: ((String?)->Void)? = nil){
  242. if let dispoables = self.associatedBinderObservables{
  243. for dis in dispoables{
  244. dis.dispose()
  245. }
  246. }
  247. self.associatedBinderObservables = []
  248. var observables : [Observable<[Any]>] = []
  249. if self is UILabel{
  250. observables.append(self.rx.methodInvoked(#selector(setter: (self as! UILabel).text)))
  251. }
  252. else if self is UIButton{
  253. observables.append(self.rx.methodInvoked(#selector((self as! UIButton).setTitle(_:for:))))
  254. }
  255. else if self is UITextField{
  256. observables.append(self.rx.methodInvoked(#selector(setter: (self as! UITextField).text)))
  257. }
  258. else{
  259. return
  260. }
  261. self.associatedBinderObservables?.append(Observable.combineLatest(observables).takeUntil(self.rx.deallocated).subscribe(onNext:{text in
  262. if let curStr = text[0][0] as? String{
  263. if !curStr.isEmpty{
  264. var beRelationStr : String?
  265. if relations?.keys.contains(curStr) ?? false{
  266. beRelationStr = relations![curStr]
  267. }
  268. for btn in binderBtns{
  269. if (btn.titleLabel?.text ?? "") == (beRelationStr ?? curStr){
  270. if !btn.isSelected{
  271. btn.isSelected = true
  272. }
  273. }
  274. else{
  275. if btn.isSelected{
  276. btn.isSelected = false
  277. }
  278. }
  279. }
  280. endBlock?(curStr)
  281. return
  282. }
  283. }
  284. endBlock?(nil)
  285. binderBtns.isSelected(false)
  286. }))
  287. for btn in binderBtns{
  288. self.associatedBinderObservables?.append(btn.rx.shareTap.takeUntil(btn.rx.deallocated).subscribe(onNext:{[unowned self] _ in
  289. if btn.isSelected{
  290. return
  291. }
  292. for curBtn in binderBtns{
  293. if curBtn == btn{
  294. curBtn.isSelected = true
  295. }
  296. else{
  297. curBtn.isSelected = false
  298. }
  299. }
  300. if let curStr = btn.titleLabel?.text{
  301. var relationStr : String?
  302. if relations.isNotNil{
  303. for key in relations!.keys{
  304. if relations![key] == curStr{
  305. relationStr = key
  306. break
  307. }
  308. }
  309. }
  310. if self is UILabel{
  311. (self as! UILabel).text = relationStr ?? curStr
  312. }
  313. else if self is UIButton{
  314. (self as! UIButton).setTitle(relationStr ?? curStr, for: (self as! UIButton).state)
  315. }
  316. else if self is UITextField{
  317. (self as! UITextField).text = relationStr ?? curStr
  318. }
  319. quickBtnTapBlock?(relationStr ?? curStr)
  320. }
  321. }))
  322. }
  323. }
  324. }
  325. extension Array where Element : UIView{
  326. var titles : [String]{
  327. get{
  328. var strs : [String] = []
  329. for label in self{
  330. if label is UILabel{
  331. strs.append((label as! UILabel).text ?? "")
  332. }
  333. else if label is UIButton{
  334. strs.append((label as! UIButton).titleLabel?.text ?? "")
  335. }
  336. else if label is UITextField{
  337. strs.append((label as! UITextField).text ?? "")
  338. }
  339. else{
  340. strs.append("")
  341. }
  342. }
  343. return strs
  344. }
  345. }
  346. }
  347. extension Array where Element : UIButton{
  348. func isSelected(_ selected: Bool){
  349. for btn in self{
  350. btn.isSelected = selected
  351. }
  352. }
  353. func setBackColor(_ color: UIColor, forState state: UIControl.State){
  354. for btn in self{
  355. btn.setBackColor(color, forState: state)
  356. }
  357. }
  358. func setBorderColor(_ borderColor: UIColor, forState state: UIControl.State){
  359. for btn in self{
  360. btn.setBorderColor(borderColor, forState: state)
  361. }
  362. }
  363. func setBorderWidth(_ borderWidth: NSString, forState state: UIControl.State){
  364. for btn in self{
  365. btn.setBorderWidth(borderWidth, forState: state)
  366. }
  367. }
  368. }
  369. ////MARK: - 地址选择
  370. //extension UITextField{
  371. //
  372. // /// 选择地址
  373. // /// - Parameters:
  374. // /// - associatedAddresses: 关联的地址数组
  375. // /// - block: MCPopSourceModel? nil 说明输入的在关联数组中找不到
  376. // public func inputAddress(_ associatedAddresses: [MCPopSourceModel], block: @escaping ((MCPopSourceModel?)->Void)){
  377. // self.keyboardType = UIKeyboardType.default
  378. // let view = UINib.view(withType: MCTextFieldAssociatedAddressView.self)
  379. // self.associatedAddress = view
  380. // view?.configView(textField: self, dataSource: associatedAddresses, selectedBlock: block)
  381. // }
  382. //
  383. //}