// // ElementUtil.swift // HCQuanfangtong // // Created by Apple on 2022/3/25. // Copyright © 2022 Jyp. All rights reserved. // import Foundation import RxSwift import RxCocoa import UIKit /// Element相关工具 //MARK: - 输入控制 InputControl extension UITextField{ // @TextFieldPhoneWrapper(block: { // // }) // @TextFieldOtherWrapper(type: .text, maxLength: 10, block:{ // // }) // @TextFieldDecimalWrapper(maxValue: 100, block: { // // }) // @TextFieldWrapper(type:.decimal, maxLength: 9, decimalLength:2, endBlock:{ // // }) // @TextFieldDegitalWrapper(maxLength: 9, maxValue: 100, block: { // // }) // var textField : UITextField? /// 9 + 2 小数限制 /// - Parameters: /// - element: <#element description#> /// - maxValue: <#maxValue description#> /// - block: <#block description#> public func inputDecimal(maxValue: Float? = nil, checkBlock: (()->Bool)? = nil, block: @escaping (()->Void)){ self.keyboardType = UIKeyboardType.decimalPad _ = self.rx.bindDelegate(delegate: MCTextFieldDelegate.decimalDefault(maxValue: maxValue, checkBlock: checkBlock, block: block)).takeUntil(self.rx.deallocated).subscribe() } /// 电话限制 /// - Parameters: /// - element: <#element description#> /// - block: <#block description#> public func inputPhone(checkBlock: (()->Bool)? = nil, block: @escaping (()->Void)){ self.keyboardType = UIKeyboardType.numberPad _ = self.rx.bindDelegate(delegate: MCTextFieldDelegate.phone(checkBlock: checkBlock, block: block)).takeUntil(self.rx.deallocated).subscribe() } /// 文本长度限制 /// - Parameters: /// - element: <#element description#> /// - maxLength: <#maxLength description#> /// - block: <#block description#> public func inputText(maxLength: Int? = nil, checkBlock: (()->Bool)? = nil, block: @escaping (()->Void)){ self.keyboardType = UIKeyboardType.default self.bindChineseDelegate(delegate: MCTextFieldDelegate.text(maxLength: maxLength, checkBlock: checkBlock, block: block)) } /// 字符长度限制 不可以输入中文 /// - Parameters: /// - maxLength: <#maxLength description#> /// - block: <#block description#> public func inputCharater(maxLength: Int? = nil, checkBlock: (()->Bool)? = nil, block: @escaping (()->Void)){ self.keyboardType = UIKeyboardType.asciiCapable _ = self.rx.bindDelegate(delegate: MCTextFieldDelegate.charater(maxLength: maxLength, checkBlock: checkBlock, block: block)).takeUntil(self.rx.deallocated).subscribe() } /// 整数强效验 不能0 开头 /// - Parameters: /// - element: <#element description#> /// - maxLength: <#maxLength description#> /// - maxValue: <#maxValue description#> /// - block: <#block description#> public func inputDegital(maxLength: Int? = nil, maxValue: Float? = nil, checkBlock: (()->Bool)? = nil, block: @escaping (()->Void)){ self.keyboardType = UIKeyboardType.numberPad _ = self.rx.bindDelegate(delegate: MCTextFieldDelegate.degital(maxLength: maxLength, maxValue: maxValue, checkBlock: checkBlock, block: block)).takeUntil(self.rx.deallocated).subscribe() } /// 整数效验 /// - Parameters: /// - element: <#element description#> /// - maxLength: <#maxLength description#> /// - maxValue: <#maxValue description#> /// - block: <#block description#> public func inputNumber(maxLength: Int? = nil, maxValue: Float? = nil, checkBlock: (()->Bool)? = nil, block: @escaping (()->Void)){ self.keyboardType = UIKeyboardType.numberPad _ = self.rx.bindDelegate(delegate: MCTextFieldDelegate.number(maxLength: maxLength, maxValue: maxValue, checkBlock: checkBlock, block: block)).takeUntil(self.rx.deallocated).subscribe() } /// 只可以输入数字和字母 /// - Parameters: /// - maxLength: <#maxLength description#> /// - block: <#block description#> public func inputNumberOrLetter(maxLength: Int? = nil, checkBlock: (()->Bool)? = nil, block: @escaping (()->Void)){ self.keyboardType = UIKeyboardType.asciiCapable _ = self.rx.bindDelegate(delegate: MCTextFieldDelegate.numberOrLetter(maxLength: maxLength, checkBlock: checkBlock, block: block)).takeUntil(self.rx.deallocated).subscribe() } /// 只可以输入中文 /// - Parameters: /// - maxLength: <#maxLength description#> /// - block: <#block description#> public func inputChinese(maxLength: Int? = nil, checkBlock: (()->Bool)? = nil, block: @escaping (()->Void)){ self.keyboardType = UIKeyboardType.default self.bindChineseDelegate(delegate: MCTextFieldDelegate.chinese(maxLength: maxLength, checkBlock: checkBlock, block: block)) } } extension UITextView{ // @TextViewWrapper(maxLength: 100, endBlock: { // // }) // var textView : UITextView? @objc(inputTextWithMaxLength: limitLabel: block:) /// 输入限制 /// - Parameters: /// - maxLength: 最大长度 /// - limitLabel: 字数限制label /// - block: 输入完 /// public func inputText(maxLength: Int, limitLabel: UILabel? = nil, block: @escaping (()->Void)){ let delegate = MCTextViewDelegate.init(maxLength: maxLength, limitLabel: limitLabel, endBlock: block) _ = self.rx.bindDelegate(delegate: delegate).takeUntil(delegate.rx.deallocated).subscribe() } } //MARK: - 关联 extension UIView{ struct AssociatedBinderKey{ static var observables = "AssociatedBinderKeyObservables" } private var associatedBinderObservables : [Disposable]?{ set{ objc_setAssociatedObject(self, &AssociatedBinderKey.observables, newValue, .OBJC_ASSOCIATION_COPY_NONATOMIC) } get{ objc_getAssociatedObject(self, &AssociatedBinderKey.observables) as? [Disposable] } } /// 绑定 /// - Parameters: /// - btns: /// - binderBtns: 被绑定的按钮数组 /// - combinText: 重组文本block /// - dismantingText: 拆解文本block /// - relations: 关联关系 static func binder(_ btns: [UIView], binderBtns:[UIButton], combinText: @escaping ([String]) -> String, dismantingText: @escaping (String) -> [String], relations: [String : String]? = nil, endBlock:(([String]?)->Void)? = nil){ for view in btns{ if let disposables = view.associatedBinderObservables{ for dis in disposables{ dis.dispose() } } } for btn in binderBtns{ if let disposables = btn.associatedBinderObservables{ for dis in disposables{ dis.dispose() } } } guard btns.count > 0 , binderBtns.count > 0 else{ return } var observables : [Observable<[Any]>] = [] for btn in btns{ if btn is UILabel{ observables.append(btn.rx.methodInvoked(#selector(setter: (btn as! UILabel).text))) } else if btn is UIButton{ observables.append(btn.rx.methodInvoked(#selector((btn as! UIButton).setTitle(_:for:)))) } else if btn is UITextField{ observables.append(btn.rx.methodInvoked(#selector(setter: (btn as! UITextField).text))) } } btns[0].associatedBinderObservables = [] btns[0].associatedBinderObservables?.append( Observable.combineLatest(observables).takeUntil(btns[0].rx.deallocated).subscribe(onNext:{text in let curStr = combinText(btns.titles) if !curStr.isEmpty{ var beRelationStr : String? if relations?.keys.contains(curStr) ?? false{ beRelationStr = relations![curStr] } for btn in binderBtns{ if btn.titleLabel?.text ?? "" == (beRelationStr ?? curStr){ if !btn.isSelected{ btn.isSelected = true } } else{ if btn.isSelected{ btn.isSelected = false } } } endBlock?(btns.titles) return } endBlock?(nil) binderBtns.isSelected(false) })) for btn in binderBtns{ btn.associatedBinderObservables = [] btn.associatedBinderObservables?.append(btn.rx.shareTap.takeUntil(btn.rx.deallocated).subscribe(onNext:{_ in if btn.isSelected{ return } for curBtn in binderBtns{ if curBtn == btn{ curBtn.isSelected = true } else{ curBtn.isSelected = false } } if let curStr = btn.titleLabel?.text{ var relationStr : String? if relations.isNotNil{ for key in relations!.keys{ if relations![key] == curStr{ relationStr = key break } } } let curStr = relationStr ?? curStr let btnsTitle = dismantingText(curStr) if btnsTitle.count == btns.count{ for i in 0..Void)? = nil, quickBtnTapBlock: ((String?)->Void)? = nil){ if let dispoables = self.associatedBinderObservables{ for dis in dispoables{ dis.dispose() } } self.associatedBinderObservables = [] var observables : [Observable<[Any]>] = [] if self is UILabel{ observables.append(self.rx.methodInvoked(#selector(setter: (self as! UILabel).text))) } else if self is UIButton{ observables.append(self.rx.methodInvoked(#selector((self as! UIButton).setTitle(_:for:)))) } else if self is UITextField{ observables.append(self.rx.methodInvoked(#selector(setter: (self as! UITextField).text))) } else{ return } self.associatedBinderObservables?.append(Observable.combineLatest(observables).takeUntil(self.rx.deallocated).subscribe(onNext:{text in if let curStr = text[0][0] as? String{ if !curStr.isEmpty{ var beRelationStr : String? if relations?.keys.contains(curStr) ?? false{ beRelationStr = relations![curStr] } for btn in binderBtns{ if (btn.titleLabel?.text ?? "") == (beRelationStr ?? curStr){ if !btn.isSelected{ btn.isSelected = true } } else{ if btn.isSelected{ btn.isSelected = false } } } endBlock?(curStr) return } } endBlock?(nil) binderBtns.isSelected(false) })) for btn in binderBtns{ self.associatedBinderObservables?.append(btn.rx.shareTap.takeUntil(btn.rx.deallocated).subscribe(onNext:{[unowned self] _ in if btn.isSelected{ return } for curBtn in binderBtns{ if curBtn == btn{ curBtn.isSelected = true } else{ curBtn.isSelected = false } } if let curStr = btn.titleLabel?.text{ var relationStr : String? if relations.isNotNil{ for key in relations!.keys{ if relations![key] == curStr{ relationStr = key break } } } if self is UILabel{ (self as! UILabel).text = relationStr ?? curStr } else if self is UIButton{ (self as! UIButton).setTitle(relationStr ?? curStr, for: (self as! UIButton).state) } else if self is UITextField{ (self as! UITextField).text = relationStr ?? curStr } quickBtnTapBlock?(relationStr ?? curStr) } })) } } } extension Array where Element : UIView{ var titles : [String]{ get{ var strs : [String] = [] for label in self{ if label is UILabel{ strs.append((label as! UILabel).text ?? "") } else if label is UIButton{ strs.append((label as! UIButton).titleLabel?.text ?? "") } else if label is UITextField{ strs.append((label as! UITextField).text ?? "") } else{ strs.append("") } } return strs } } } extension Array where Element : UIButton{ func isSelected(_ selected: Bool){ for btn in self{ btn.isSelected = selected } } func setBackColor(_ color: UIColor, forState state: UIControl.State){ for btn in self{ btn.setBackColor(color, forState: state) } } func setBorderColor(_ borderColor: UIColor, forState state: UIControl.State){ for btn in self{ btn.setBorderColor(borderColor, forState: state) } } func setBorderWidth(_ borderWidth: NSString, forState state: UIControl.State){ for btn in self{ btn.setBorderWidth(borderWidth, forState: state) } } } ////MARK: - 地址选择 //extension UITextField{ // // /// 选择地址 // /// - Parameters: // /// - associatedAddresses: 关联的地址数组 // /// - block: MCPopSourceModel? nil 说明输入的在关联数组中找不到 // public func inputAddress(_ associatedAddresses: [MCPopSourceModel], block: @escaping ((MCPopSourceModel?)->Void)){ // self.keyboardType = UIKeyboardType.default // let view = UINib.view(withType: MCTextFieldAssociatedAddressView.self) // self.associatedAddress = view // view?.configView(textField: self, dataSource: associatedAddresses, selectedBlock: block) // } // //}