// // VerificationPopView.swift // QuickLocation // // Created by 八条 on 2026/6/10. // import UIKit import RxSwift import RxCocoa import IQKeyboardManagerSwift class VerificationPopView: UIView { private static let shared = VerificationPopView(frame: CGRect(origin: .zero, size: kScreenSize)) var disposeBag = DisposeBag() private var completion: (() -> Void)? static func show(completion: @escaping (() -> Void)) { guard let superView = kKeyWindow else { return } if VerificationPopView.shared.superview != nil { VerificationPopView.shared.removeFromSuperview() VerificationPopView.shared.bgView.frame = .zero } VerificationPopView.shared.num1Lab.text = "\(Int.random(in: 1...9))" VerificationPopView.shared.num2Lab.text = "\(Int.random(in: 1...9))" VerificationPopView.shared.resultTF.text = "" VerificationPopView.shared.bgView.alpha = 1 VerificationPopView.shared.bgView.frame = CGRect(x: 0, y: 0, width: kScreenWidth, height: kScreenHeight) superView.addSubview(VerificationPopView.shared) superView.bringSubviewToFront(VerificationPopView.shared) UIView.animate(withDuration: 0.25) { VerificationPopView.shared.bgView.alpha = 1 } completion: { _ in VerificationPopView.shared.resultTF.becomeFirstResponder() } VerificationPopView.shared.completion = { completion() VerificationPopView.dismiss() } IQKeyboardManager.shared.resignOnTouchOutside = false } /// 关闭 static func dismiss() { guard VerificationPopView.shared.superview != nil else { return } UIView.animate(withDuration: 0.25, delay: 0, options: [.curveEaseIn]) { VerificationPopView.shared.bgView.alpha = 0 } completion: { _ in VerificationPopView.shared.removeFromSuperview() IQKeyboardManager.shared.resignOnTouchOutside = true } } private func setupRx() { resultTF.rx.text .bind(to: resultLab.rx.text) .disposed(by: disposeBag) resultTF.rx.text.orEmpty .subscribe(onNext: { [weak self] text in guard let self = self, let num1 = self.num1Lab.text, let num2 = self.num2Lab.text else { return } let result = num1.integer + num2.integer if !text.isEmpty { self.resultIconView.image = UIImage(named: result == text.integer ? "Popup/correct" : "Popup/error") self.confirmBtn.isEnabled = result == text.integer } else { self.resultIconView.image = nil self.confirmBtn.isEnabled = false } }) .disposed(by: disposeBag) confirmBtn.rx.tap.subscribe(onNext: { _ in self.completion?() }).disposed(by: disposeBag) closeBtn.rx.tap.subscribe(onNext: { _ in VerificationPopView.dismiss() }).disposed(by: disposeBag) } private lazy var bgView: UIView = { let view = UIView() view.backgroundColor = .black.withAlphaComponent(0.5) return view }() lazy var popView: UIView = { let view = UIView() view.backgroundColor = .clear return view }() lazy var popBgView: UIView = { let view = UIView() view.backgroundColor = .white view.cornerRadius = 30 return view }() lazy var logoImgView: UIImageView = { let view = UIImageView(image: UIImage(named: "Popup/bell")) return view }() lazy var headerBgImg: UIImageView = { let view = UIImageView(image: UIImage(named: "Popup/header_bg")) view.contentMode = .scaleAspectFill return view }() lazy var titleLab: UILabel = { let label = UILabel() label.text = "确定要离开这个圈子吗?" label.font = .systemFont(ofSize: 20, weight: .bold) label.textColor = UIColor(hexStr: "#1A1A1A") label.textAlignment = .center label.numberOfLines = 0 return label }() lazy var contentLab: UILabel = { let label = UILabel() label.text = "您离开后将解散圈子,确定 要解散吗?" label.font = .systemFont(ofSize: 14, weight: .medium) label.textColor = UIColor(hexStr: "#767676") label.textAlignment = .center label.numberOfLines = 0 return label }() lazy var tipsLab: UILabel = { let label = UILabel() label.text = "请验证:填写组合数字,相加后需等于给定数值" label.font = .systemFont(ofSize: 8, weight: .medium) label.textColor = UIColor(hexStr: "#999999") label.textAlignment = .center label.numberOfLines = 0 return label }() lazy var equationView: UIView = { let view = UIView() view.backgroundColor = .clear let addLab = UILabel() addLab.text = "+" addLab.font = .systemFont(ofSize: 16, weight: .medium) addLab.textColor = UIColor(hexStr: "#999999") let equalLab = UILabel() equalLab.text = "=" equalLab.font = .systemFont(ofSize: 16, weight: .medium) equalLab.textColor = UIColor(hexStr: "#999999") view.addSubview(num1View) view.addSubview(addLab) view.addSubview(num2View) view.addSubview(equalLab) view.addSubview(resultView) view.addSubview(resultIconView) num1View.layoutChain .left() .edgesVertical() .width(30) .height(30) addLab.layoutChain .leftToRightOfView(num1View, offset: 13) .centerY() num2View.layoutChain .topToView(num1View) .leftToRightOfView(addLab, offset: 13) .width(30) .height(30) equalLab.layoutChain .leftToRightOfView(num2View, offset: 13) .centerY() resultView.layoutChain .topToView(num1View) .leftToRightOfView(equalLab, offset: 13) .height(30) .width(30) resultIconView.layoutChain .leftToRightOfView(resultView, offset: 10) .centerY() .right() return view }() lazy var num1View: UIView = { let view = UIView() view.backgroundColor = UIColor(hexStr: "#EFF9FF") view.cornerRadius = 2 view.addSubview(num1Lab) num1Lab.layoutChain .edges() return view }() lazy var num1Lab: UILabel = { let label = UILabel() label.font = .systemFont(ofSize: 16, weight: .medium) label.textColor = UIColor(hexStr: "#666666") label.textAlignment = .center return label }() lazy var num2View: UIView = { let view = UIView() view.backgroundColor = UIColor(hexStr: "#EFF9FF") view.cornerRadius = 2 view.addSubview(num2Lab) num2Lab.layoutChain .edges() return view }() lazy var num2Lab: UILabel = { let label = UILabel() label.font = .systemFont(ofSize: 16, weight: .medium) label.textColor = UIColor(hexStr: "#666666") label.textAlignment = .center return label }() lazy var resultView: UIView = { let view = UIView() view.backgroundColor = UIColor(hexStr: "#5CBBFF") view.cornerRadius = 2 view.addSubview(resultTF) view.addSubview(resultLab) resultLab.layoutChain .edges(all: 4) return view }() lazy var resultTF: UITextField = { let tf = UITextField() tf.keyboardType = .numberPad tf.returnKeyType = .done tf.isHidden = true return tf }() lazy var resultLab: UILabel = { let label = UILabel() label.font = .systemFont(ofSize: 16, weight: .medium) label.textColor = .white//UIColor(hexStr: "#16B3FF") label.textAlignment = .center return label }() lazy var resultIconView: UIImageView = { let view = UIImageView() view.backgroundColor = .clear return view }() lazy var confirmBtn: UIButton = { let btn = UIButton(type: .custom) btn.setTitle("是", for: .normal) btn.setTitleColor(UIColor(hexStr: "#16B3FF"), for: .normal) btn.titleLabel?.font = .systemFont(ofSize: 16, weight: .medium) btn.backgroundColor = .clear btn.isEnabled = false return btn }() lazy var closeBtn: UIButton = { let btn = UIButton(type: .custom) btn.setTitle("否", for: .normal) btn.setTitleColor(UIColor(hexStr: "#0F2846"), for: .normal) btn.titleLabel?.font = .systemFont(ofSize: 16, weight: .medium) btn.setBackgroundImage(UIImage(named: "Common/button_bg_2"), for: .normal) btn.cornerRadius = 25 return btn }() // MARK: - Init override init(frame: CGRect) { super.init(frame: frame) backgroundColor = .clear addSubview(bgView) bgView.addSubview(popView) popView.addSubview(popBgView) popView.addSubview(logoImgView) popBgView.addSubview(headerBgImg) popBgView.addSubview(titleLab) popBgView.addSubview(contentLab) popBgView.addSubview(tipsLab) popBgView.addSubview(equationView) popBgView.addSubview(confirmBtn) popBgView.addSubview(closeBtn) popView.layoutChain .centerY(self, offset: -40) .centerX() .width(315) popBgView.layoutChain.edges() logoImgView.layoutChain .left(16) .top(-45) .width(109) .height(109) headerBgImg.layoutChain .edges(excludingEdge: .bottom) .heightToWidth(100/315) titleLab.layoutChain .top(53) .centerX() contentLab.layoutChain .topToBottomOfView(titleLab, offset: 10) .edgesHorzontal(20) tipsLab.layoutChain .topToBottomOfView(contentLab, offset: 8) .centerX() equationView.layoutChain .topToBottomOfView(tipsLab, offset: 6) .centerX() .height(30) closeBtn.layoutChain .topToBottomOfView(equationView, offset: 20) .edgesHorzontal(20) .height(50) confirmBtn.layoutChain .topToBottomOfView(closeBtn, offset: 10) .edgesHorzontal(20) .height(50) .bottom(10) setupRx() } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func layoutSubviews() { super.layoutSubviews() } }