268 lines
8.6 KiB
Swift
268 lines
8.6 KiB
Swift
//
|
||
// OneTapLoginView.swift
|
||
// QuickLocation
|
||
//
|
||
// Created by 八条 on 2026/5/28.
|
||
//
|
||
|
||
import UIKit
|
||
import RxSwift
|
||
import RxCocoa
|
||
#if !targetEnvironment(simulator)
|
||
import GeYanSdk
|
||
#endif
|
||
|
||
class OneTapLoginView: UIView {
|
||
|
||
var disposeBag = DisposeBag()
|
||
var oneTapLogin = true
|
||
|
||
private func setupRx() {
|
||
backBtn.rx.tap.subscribe(onNext: { _ in
|
||
#if !targetEnvironment(simulator)
|
||
GeYanSdk.closeAuthVC(true, completion: nil)
|
||
#endif
|
||
}).disposed(by: disposeBag)
|
||
|
||
checkBox.rx.tap.subscribe(onNext: { [weak self] in
|
||
guard let self = self else { return }
|
||
self.checkBox.isSelected = !self.checkBox.isSelected
|
||
}).disposed(by: disposeBag)
|
||
|
||
agreementTV.delegate = self
|
||
}
|
||
|
||
func setupAgreementTextWithCarrier(carrier: String) {
|
||
let text = "登录即同意\(carrier)、《隐私政策》和《用户协议》"
|
||
agreementLabel.text = text
|
||
// 创建段落样式
|
||
let paragraphStyle = NSMutableParagraphStyle()
|
||
// 设置行距(lineSpacing 是行间距,lineHeightMultiple 是行高倍数)
|
||
paragraphStyle.lineSpacing = 4.0 // 行间距
|
||
|
||
let attributedString = NSMutableAttributedString(string: text)
|
||
attributedString.addAttributes([.foregroundColor: UIColor(hexStr: "#A4A7AE"),
|
||
.paragraphStyle: paragraphStyle], range: NSRange(location: 0, length: text.length))
|
||
attributedString.addAttributes([.foregroundColor: UIColor(hexStr: "#16B3FF"),
|
||
.link: "Carrier"],
|
||
range: (text as NSString).range(of: carrier))
|
||
attributedString.addAttributes([.foregroundColor: UIColor(hexStr: "#16B3FF"),
|
||
.link: "UserAgreement"],
|
||
range: (text as NSString).range(of: "《用户协议》"))
|
||
attributedString.addAttributes([.foregroundColor: UIColor(hexStr: "#16B3FF"),
|
||
.link: "PrivacyPolicy"],
|
||
range: (text as NSString).range(of: "《隐私政策》"))
|
||
|
||
agreementTV.attributedText = attributedString
|
||
}
|
||
|
||
private func setupUI() {
|
||
addSubview(bgMaskImage)
|
||
addSubview(backBtn)
|
||
addSubview(inputContainerView)
|
||
inputContainerView.addSubview(welcomeLabel)
|
||
inputContainerView.addSubview(phoneNumberLabel)
|
||
inputContainerView.addSubview(carrierLabel)
|
||
inputContainerView.addSubview(loginButton)
|
||
|
||
addSubview(agreementView)
|
||
agreementView.addSubview(checkBox)
|
||
agreementView.addSubview(agreementLabel)
|
||
agreementView.addSubview(agreementTV)
|
||
|
||
bgMaskImage.layoutChain.edges()
|
||
|
||
backBtn.layoutChain
|
||
.top(54)
|
||
.left(15)
|
||
.width(24)
|
||
.height(24)
|
||
|
||
inputContainerView.layoutChain
|
||
.centerX()
|
||
.centerY()
|
||
.edgesHorzontal()
|
||
.height(301)
|
||
|
||
welcomeLabel.layoutChain
|
||
.top(0)
|
||
.centerX()
|
||
.edgesHorzontal()
|
||
|
||
phoneNumberLabel.layoutChain
|
||
.topToBottomOfView(welcomeLabel, offset: 78)
|
||
.centerX()
|
||
|
||
carrierLabel.layoutChain
|
||
.topToBottomOfView(phoneNumberLabel, offset: 4)
|
||
.centerX()
|
||
|
||
loginButton.layoutChain
|
||
.topToBottomOfView(carrierLabel, offset: 99)
|
||
.centerX()
|
||
.width(247)
|
||
.height(50)
|
||
|
||
agreementView.layoutChain
|
||
.edgesHorzontal(30)
|
||
.bottom(kSafeBottomMargin + 20)
|
||
|
||
checkBox.layoutChain
|
||
.left()
|
||
.top(10)
|
||
.width(12)
|
||
.height(12)
|
||
|
||
agreementLabel.layoutChain
|
||
.leftToRightOfView(checkBox, offset: 0)
|
||
.right()
|
||
.top()
|
||
.bottom()
|
||
|
||
agreementTV.layoutChain
|
||
.leftToRightOfView(checkBox, offset: 0)
|
||
.right()
|
||
.top()
|
||
.bottom()
|
||
}
|
||
|
||
override init(frame: CGRect) {
|
||
super.init(frame: frame)
|
||
backgroundColor = .white
|
||
setupUI()
|
||
setupRx()
|
||
|
||
if let model = GyContentModel.current() {
|
||
phoneNumberLabel.text = model.pn
|
||
carrierLabel.text = model.slogan
|
||
setupAgreementTextWithCarrier(carrier: model.term)
|
||
}
|
||
}
|
||
|
||
required init?(coder aDecoder: NSCoder) {
|
||
fatalError("init(coder:) has not been implemented")
|
||
}
|
||
|
||
// MARK: - UI Components
|
||
lazy var inputContainerView: UIView = {
|
||
let view = UIView()
|
||
view.backgroundColor = .clear
|
||
return view
|
||
}()
|
||
|
||
lazy var bgMaskImage: UIImageView = {
|
||
let iv = UIImageView()
|
||
iv.image = UIImage(named: "Login/bg")
|
||
iv.contentMode = .scaleAspectFill
|
||
return iv
|
||
}()
|
||
|
||
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: 50, right: 50)
|
||
return btn
|
||
}()
|
||
|
||
lazy var welcomeLabel: UILabel = {
|
||
let label = UILabel()
|
||
label.text = "欢迎登录"
|
||
label.font = UIFont(name: "DOUYU Font", size: 24)
|
||
label.textColor = UIColor(hexStr: "#030303")
|
||
label.textAlignment = .center
|
||
return label
|
||
}()
|
||
|
||
lazy var phoneNumberLabel: UILabel = {
|
||
let label = UILabel()
|
||
label.font = .systemFont(ofSize: 20, weight: .medium)
|
||
label.textColor = ThemeManager.shared.color.titleAuxColor
|
||
label.textAlignment = .center
|
||
return label
|
||
}()
|
||
|
||
lazy var carrierLabel: UILabel = {
|
||
let label = UILabel()
|
||
label.font = .systemFont(ofSize: 12)
|
||
label.textColor = ThemeManager.shared.color.contentColor
|
||
label.textAlignment = .center
|
||
return label
|
||
}()
|
||
|
||
lazy var loginButton: UIButton = {
|
||
let btn = UIButton(type: .system)
|
||
btn.setTitle("本机号码一键登录", for: .normal)
|
||
btn.setTitleColor(UIColor(hexStr: "#0F2846"), for: .normal)
|
||
btn.titleLabel?.font = .systemFont(ofSize: 16, weight: .medium)
|
||
btn.setBackgroundImage(UIImage(named: "Login/login_bg"), for: .normal)
|
||
return btn
|
||
}()
|
||
|
||
lazy var label: UILabel = {
|
||
let label = UILabel()
|
||
|
||
return label
|
||
}()
|
||
|
||
lazy var agreementView: UIView = {
|
||
let view = UIView()
|
||
view.backgroundColor = .clear
|
||
return view
|
||
}()
|
||
|
||
lazy var checkBox: UIButton = {
|
||
let btn = UIButton(type: .custom)
|
||
btn.setImage(UIImage(named: "Login/checkbox"), for: .normal)
|
||
btn.setImage(UIImage(named: "Login/selected"), for: .selected)
|
||
btn.extendEdgeInsets = UIEdgeInsets(top: 50, left: 50, bottom: 50, right: 20)
|
||
btn.isSelected = true
|
||
return btn
|
||
}()
|
||
|
||
lazy var agreementLabel: UILabel = {
|
||
let label = UILabel()
|
||
label.textColor = .clear
|
||
label.numberOfLines = 0
|
||
// label.textAlignment = .center
|
||
label.font = .systemFont(ofSize: 10)
|
||
return label
|
||
}()
|
||
|
||
lazy var agreementTV: UITextView = {
|
||
let textView = UITextView()
|
||
textView.font = .systemFont(ofSize: 10, weight: .medium)
|
||
textView.backgroundColor = .clear
|
||
textView.isEditable = false
|
||
textView.isScrollEnabled = false
|
||
textView.isSelectable = true
|
||
textView.linkTextAttributes = [:]
|
||
|
||
return textView
|
||
}()
|
||
}
|
||
|
||
#if !targetEnvironment(simulator)
|
||
extension OneTapLoginView: UITextViewDelegate {
|
||
func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
|
||
var urlStr: String?
|
||
if URL.absoluteString == "Carrier", let model = GyContentModel.current(), let link = model.link {
|
||
urlStr = link
|
||
}
|
||
if URL.absoluteString == "UserAgreement" {
|
||
urlStr = URLManager.shared.userAgreementUrl
|
||
}
|
||
if URL.absoluteString == "PrivacyPolicy" {
|
||
urlStr = URLManager.shared.privacyPolicyUrl
|
||
}
|
||
guard let urlString = urlStr else { return true }
|
||
let vc = WebViewController(url: urlString, isShare: false, fullscreen: false, style: "default")
|
||
AppRouter.present(UINavigationController(rootViewController: vc))
|
||
return true
|
||
}
|
||
|
||
func textViewShouldBeginEditing(_ textView: UITextView) -> Bool {
|
||
false
|
||
}
|
||
}
|
||
#endif
|