// // EmergencyContactAddView.swift // QuickLocation // // Created by 八条 on 2026/6/11. // import UIKit import RxSwift import RxCocoa class EmergencyContactAddView: UIView { var disposeBag = DisposeBag() private func setupRx() { nameTF.rx.text .map { text -> String? in guard let text = text else { return nil } return String(text.prefix(10)) }.bind(to: nameTF.rx.text) .disposed(by: disposeBag) phoneTF.rx.text .map { text -> String? in guard let text = text else { return nil } return String(text.filter { $0.isASCII && $0.isNumber }.prefix(11)) }.bind(to: phoneTF.rx.text) .disposed(by: disposeBag) let valid = Observable.combineLatest(nameTF.rx.text.orEmpty, phoneTF.rx.text.orEmpty) .map { name, phone in !name.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty && phone.count == 11 } .share(replay: 1) valid.bind(to: saveBtn.rx.isEnabled).disposed(by: disposeBag) valid.map { $0 ? 1.0 : 0.5 }.bind(to: saveBtn.rx.alpha).disposed(by: disposeBag) nameRow.rx.tapGesture.subscribe(onNext: { [weak self] _ in self?.nameTF.becomeFirstResponder() }).disposed(by: disposeBag) phoneRow.rx.tapGesture.subscribe(onNext: { [weak self] _ in self?.phoneTF.becomeFirstResponder() }).disposed(by: disposeBag) } private func setupUI() { addSubview(navBgView) addSubview(navView) addSubview(cardView) addSubview(saveBtn) navBgView.layoutChain .edges(excludingEdge: .bottom) .heightToWidth(160 / 375) navView.layoutChain .edges(excludingEdge: .bottom) .height(kNaviHeight) cardView.layoutChain .topToBottomOfView(navView, offset: 16) .edgesHorzontal(15) saveBtn.layoutChain .edgesHorzontal(30) .bottom(kSafeBottomMargin + 12) .height(56) } lazy var navBgView: UIImageView = { let iv = UIImageView() iv.image = UIImage(named: "Common/navBar_bg_2") iv.contentMode = .scaleAspectFill return iv }() lazy var navView: BaseNavigationView = { BaseNavigationView(title: "添加紧急联系人") }() lazy var cardView: UIView = { let view = UIView() view.backgroundColor = .white view.cornerRadius = 16 view.addSubview(nameRow) nameRow.layoutChain .top() .edgesHorzontal() .height(56) let line = UIView() line.backgroundColor = UIColor(hexStr: "#F0F2F5") view.addSubview(line) line.layoutChain .topToBottomOfView(nameRow) .left(16) .right(16) .height(0.5) view.addSubview(phoneRow) phoneRow.layoutChain .topToBottomOfView(line) .edgesHorzontal() .bottom() .height(56) return view }() lazy var nameRow: UIView = { makeInputRow(title: "姓名", textField: nameTF, arrow: nameArrow) }() lazy var phoneRow: UIView = { makeInputRow(title: "手机号", textField: phoneTF, arrow: phoneArrow) }() lazy var nameTF: UITextField = { let textField = UITextField() textField.returnKeyType = .done textField.textAlignment = .right textField.placeholder = "请输入姓名" textField.font = .systemFont(ofSize: 15, weight: .regular) textField.textColor = UIColor(hexStr: "#0F2846") textField.attributedPlaceholder = NSAttributedString( string: "请输入姓名", attributes: [.foregroundColor: UIColor(hexStr: "#C5CAD3")] ) return textField }() lazy var phoneTF: UITextField = { let textField = UITextField() textField.keyboardType = .numberPad textField.returnKeyType = .done textField.textAlignment = .right textField.font = .systemFont(ofSize: 15, weight: .regular) textField.textColor = UIColor(hexStr: "#0F2846") textField.attributedPlaceholder = NSAttributedString( string: "请输入手机号", attributes: [.foregroundColor: UIColor(hexStr: "#C5CAD3")] ) return textField }() lazy var nameArrow: UIImageView = { makeArrow() }() lazy var phoneArrow: UIImageView = { makeArrow() }() lazy var saveBtn: UIButton = { let btn = UIButton(type: .custom) btn.setTitle("保存", for: .normal) btn.titleLabel?.font = FontManager.boboBold(18) btn.setTitleColor(.white, for: .normal) btn.setBackgroundImage(UIImage(named: "Common/button_bg_2"), for: .normal) btn.cornerRadius = 20 btn.isEnabled = false return btn }() private func makeInputRow(title: String, textField: UITextField, arrow: UIImageView) -> UIView { let view = UIView() view.backgroundColor = .clear let titleLab = UILabel() titleLab.text = title titleLab.font = .systemFont(ofSize: 16, weight: .medium) titleLab.textColor = UIColor(hexStr: "#0F2846") view.addSubview(titleLab) titleLab.layoutChain .left(16) .centerY() view.addSubview(arrow) arrow.layoutChain .right(16) .centerY() .width(16) .height(16) view.addSubview(textField) textField.layoutChain .left(88) .rightToLeftOfView(arrow, offset: -6) .edgesVertical() return view } private func makeArrow() -> UIImageView { let view = UIImageView(image: UIImage(named: "EmergencyContact/arrow_right")) view.contentMode = .scaleAspectFit return view } override init(frame: CGRect) { super.init(frame: .zero) backgroundColor = UIColor(hexStr: "#F7F8FA") setupUI() setupRx() } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } }