// // ChangePhoneView.swift // QuickLocation // // Created by 八条 on 2026/6/11. // import UIKit import RxSwift import RxCocoa class ChangePhoneView: UIView { var disposeBag = DisposeBag() private func setupRx() { phoneTF.rx.text .map { text -> String? in guard let text = text else { return nil } return String(text.prefix(11)) }.bind(to: phoneTF.rx.text) .disposed(by: disposeBag) phoneTF.rx.text.orEmpty.map { phone -> Bool in if phone.count == 11 { return true } else { return false } } .bind(to: smsCodeBtn.rx.isEnabled) .disposed(by: disposeBag) codeTF.rx.text .map { text -> String? in guard let text = text else { return nil } return String(text.prefix(6)) }.bind(to: codeTF.rx.text) .disposed(by: disposeBag) let form = Observable.combineLatest(phoneTF.rx.text.orEmpty, codeTF.rx.text.orEmpty) form.map { phone, smsCode -> Bool in if phone.count == 11 && smsCode.count >= 1 { return true } else { return false } } .bind(to: confirmBtn.rx.isEnabled) .disposed(by: disposeBag) backBtn.rx.tap.subscribe(onNext: { _ in AppRouter.shared.popOrDismiss() }).disposed(by: disposeBag) } private func setupUI() { addSubview(navBgView) addSubview(navBarView) navBarView.addSubview(navTitleLabel) navBarView.addSubview(backBtn) addSubview(confirmBtn) addSubview(infoShadowView) infoShadowView.addSubview(infoView) infoView.addSubview(phoneInputView) infoView.addSubview(codeInputView) navBgView.layoutChain .edges(excludingEdge: .bottom) .heightToWidth(160/375) navBarView.layoutChain .edges(excludingEdge: .bottom) .height(kNaviHeight) navTitleLabel.layoutChain .top(kStatusBarHeight + 12) .centerY(backBtn) .centerX() backBtn.layoutChain .centerY(navTitleLabel) .left(15) .width(24) .height(24) infoShadowView.layoutChain .topToBottomOfView(navBarView, offset: 18) .edgesHorzontal(16) infoView.layoutChain.edges() phoneInputView.layoutChain .edges(excludingEdge: .bottom) .height(52) codeInputView.layoutChain .topToBottomOfView(phoneInputView) .edgesHorzontal() .bottom() .height(52) confirmBtn.layoutChain .edgesHorzontal(30) .bottom(kSafeBottomMargin + 30) .height(50) } lazy var navBgView: UIImageView = { let iv = UIImageView() iv.image = UIImage(named: "Common/navBar_bg_2") iv.contentMode = .scaleAspectFill return iv }() lazy var navBarView: UIView = { let view = UIView() view.backgroundColor = .clear return view }() lazy var navTitleLabel: UILabel = { let label = UILabel() label.text = "更换手机号" label.font = .systemFont(ofSize: 18, weight: .medium) label.textColor = ThemeManager.shared.color.titleAuxColor label.textAlignment = .center return label }() lazy var backBtn: UIButton = { let btn = UIButton(type: .custom) btn.setImage(UIImage(named: "Common/back"), for: .normal) btn.extendEdgeInsets = UIEdgeInsets(top: 54, left: 15, bottom: 100, right: 100) return btn }() lazy var infoShadowView: UIView = { let view = UIView() view.backgroundColor = .clear view.layer.shadowColor = UIColor(hexStr: "#0F2846", alpha: 0.1).cgColor view.layer.shadowOffset = CGSize(width: 0, height: 0) view.layer.shadowOpacity = 1 view.layer.shadowRadius = 10 return view }() lazy var infoView: UIView = { let view = UIView() view.backgroundColor = .white view.cornerRadius = 10 return view }() // 手机号 lazy var phoneInputView: UIView = { let view = UIView() view.backgroundColor = .clear let titleLab = UILabel() titleLab.text = "手机号" titleLab.font = .systemFont(ofSize: 14, weight: .medium) titleLab.textColor = UIColor(hexStr: "#1A1A1A") view.addSubview(titleLab) titleLab.layoutChain .left(15) .centerY() view.addSubview(phoneTF) phoneTF.layoutChain .right(15) .edgesVertical() .width(200) let line = UIView() line.backgroundColor = ThemeManager.shared.color.lineColor view.addSubview(line) line.layoutChain .bottom() .height(0.5) .edgesHorzontal(15) return view }() lazy var phoneTF: UITextField = { let textField = UITextField() textField.keyboardType = .numberPad textField.returnKeyType = .done textField.textAlignment = .right textField.placeholder = "请输入您要更换的手机号" textField.font = .systemFont(ofSize: 14, weight: .medium) return textField }() // 验证码 lazy var codeInputView: UIView = { let view = UIView() view.backgroundColor = .clear let titleLab = UILabel() titleLab.text = "验证码" titleLab.font = .systemFont(ofSize: 14, weight: .medium) titleLab.textColor = UIColor(hexStr: "#1A1A1A") view.addSubview(titleLab) titleLab.layoutChain .left(15) .centerY() view.addSubview(smsCodeBtn) smsCodeBtn.layoutChain .right(15) .edgesVertical() .width(80) view.addSubview(codeTF) codeTF.layoutChain .rightToLeftOfView(smsCodeBtn, offset: -15) .edgesVertical() .width(150) return view }() lazy var codeTF: UITextField = { let textField = UITextField() textField.keyboardType = .numberPad textField.returnKeyType = .done textField.textAlignment = .right textField.placeholder = "请输入验证码" textField.font = .systemFont(ofSize: 14, weight: .medium) return textField }() lazy var smsCodeBtn: UIButton = { let button = UIButton() button.setTitle("发送验证码", for: .normal) button.setTitleColor(UIColor(hexStr: "#16B3FF"), for: .normal) button.setTitleColor(UIColor(hexStr: "#999999", alpha: 1.0), for: .disabled) button.titleLabel?.font = .systemFont(ofSize: 14, weight: .medium) button.backgroundColor = .clear return button }() lazy var confirmBtn: UIButton = { let btn = UIButton(type: .custom) btn.setTitle("确认", for: .normal) btn.titleLabel?.font = .systemFont(ofSize: 16, weight: .medium) btn.setTitleColor(.white, for: .normal) btn.setBackgroundImage(UIImage(named: "Common/button_bg_2"), for: .normal) btn.cornerRadius = 25 return btn }() override init(frame: CGRect) { super.init(frame: .zero) backgroundColor = UIColor(hexStr: "#FAFAFA") setupUI() setupRx() } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } }