Files
suixinkan_uikit/suixinkan/UI/Login/LoginViewController.swift

225 lines
7.7 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// LoginViewController.swift
// suixinkan
//
import SnapKit
import UIKit
/// UI Android `LoginScreen`
final class LoginViewController: BaseViewController {
private let viewModel = LoginViewModel()
private let backgroundImageView = UIImageView()
private let welcomeLabel = UILabel()
private let formCardView = UIView()
private let topFormStack = UIStackView()
private let accountField = LoginTextField(placeholder: "请输入账号")
private let passwordField = PasswordInputField()
private let agreementRow = AgreementRowView()
private let loginButton = AppButton(title: "登录", style: .primary)
private let loginByCodeButton = AppButton(title: "验证码登录", style: .secondary)
private let registerContainer = UIStackView()
private let registerPrefixLabel = UILabel()
private let registerButton = UIButton(type: .system)
private var hasPlayedEntranceAnimation = false
override var preferredStatusBarStyle: UIStatusBarStyle {
.lightContent
}
override func setupNavigationBar() {
navigationController?.setNavigationBarHidden(true, animated: false)
}
override func setupUI() {
view.backgroundColor = .black
backgroundImageView.image = UIImage(named: "img_login_bg")
backgroundImageView.contentMode = .scaleAspectFill
backgroundImageView.clipsToBounds = true
welcomeLabel.text = "欢迎使用\n随心瞰商家版"
welcomeLabel.numberOfLines = 2
welcomeLabel.font = .systemFont(ofSize: 28, weight: .semibold)
welcomeLabel.textColor = .white
formCardView.backgroundColor = .white
formCardView.layer.cornerRadius = 16
formCardView.clipsToBounds = true
topFormStack.axis = .vertical
topFormStack.spacing = 0
topFormStack.alignment = .fill
loginButton.addTarget(self, action: #selector(loginButtonTapped), for: .touchUpInside)
loginByCodeButton.addTarget(self, action: #selector(loginByCodeButtonTapped), for: .touchUpInside)
registerContainer.axis = .horizontal
registerContainer.alignment = .center
registerContainer.spacing = 0
registerPrefixLabel.text = "没有账号?"
registerPrefixLabel.font = .systemFont(ofSize: 14, weight: .medium)
registerPrefixLabel.textColor = AppColor.text333
registerButton.setTitle("去注册", for: .normal)
registerButton.titleLabel?.font = .systemFont(ofSize: 14, weight: .medium)
registerButton.setTitleColor(AppColor.primary, for: .normal)
registerButton.addTarget(self, action: #selector(registerButtonTapped), for: .touchUpInside)
registerContainer.addArrangedSubview(registerPrefixLabel)
registerContainer.addArrangedSubview(registerButton)
view.addSubview(backgroundImageView)
view.addSubview(welcomeLabel)
view.addSubview(formCardView)
formCardView.addSubview(topFormStack)
formCardView.addSubview(registerContainer)
topFormStack.addArrangedSubview(accountField)
topFormStack.setCustomSpacing(8, after: accountField)
topFormStack.addArrangedSubview(passwordField)
topFormStack.setCustomSpacing(24, after: passwordField)
topFormStack.addArrangedSubview(agreementRow)
topFormStack.setCustomSpacing(16, after: agreementRow)
topFormStack.addArrangedSubview(loginButton)
topFormStack.setCustomSpacing(8, after: loginButton)
topFormStack.addArrangedSubview(loginByCodeButton)
bindViewModel()
updateUI()
}
override func setupConstraints() {
backgroundImageView.snp.makeConstraints { make in
make.edges.equalToSuperview()
}
welcomeLabel.snp.makeConstraints { make in
make.top.equalTo(view.safeAreaLayoutGuide).offset(48)
make.leading.trailing.equalToSuperview().inset(24)
}
formCardView.snp.makeConstraints { make in
make.top.equalTo(welcomeLabel.snp.bottom).offset(48)
make.leading.trailing.equalToSuperview().inset(24)
make.bottom.equalTo(view.safeAreaLayoutGuide).offset(-24)
}
topFormStack.snp.makeConstraints { make in
make.top.leading.trailing.equalToSuperview().inset(16)
make.bottom.equalToSuperview().inset(16)
}
registerContainer.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.bottom.equalToSuperview().inset(16)
}
}
override func bindActions() {
accountField.onTextChange = { [weak self] text in
self?.viewModel.updateAccount(text)
}
accountField.onReturnKey = { [weak self] in
self?.passwordField.becomeFirstResponder()
}
passwordField.onTextChange = { [weak self] text in
self?.viewModel.updatePassword(text)
}
passwordField.onReturnKey = { [weak self] in
self?.view.endEditing(true)
self?.viewModel.login()
}
agreementRow.onCheckedChange = { [weak self] in
self?.viewModel.togglePrivacyChecked()
}
agreementRow.onUserAgreementTap = { [weak self] in
self?.viewModel.onUserAgreement?()
}
agreementRow.onPrivacyPolicyTap = { [weak self] in
self?.viewModel.onPrivacyPolicy?()
}
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
playEntranceAnimationIfNeeded()
}
private func bindViewModel() {
viewModel.onStateChange = { [weak self] in
self?.updateUI()
}
viewModel.onShowMessage = { [weak self] message in
self?.showToast(message)
}
viewModel.onLogin = { [weak self] in
self?.showToast("登录功能待接入")
}
viewModel.onLoginByCode = { [weak self] in
self?.showToast("验证码登录待接入")
}
viewModel.onRegister = { [weak self] in
self?.showToast("注册待接入")
}
viewModel.onUserAgreement = { [weak self] in
self?.showToast("用户协议待接入")
}
viewModel.onPrivacyPolicy = { [weak self] in
self?.showToast("隐私政策待接入")
}
}
private func updateUI() {
agreementRow.isChecked = viewModel.isPrivacyChecked
loginButton.isEnabled = viewModel.isLoginEnabled
let showRegisterSection = viewModel.enableRegister
loginByCodeButton.isHidden = !showRegisterSection
registerContainer.isHidden = !showRegisterSection
topFormStack.snp.remakeConstraints { make in
make.top.leading.trailing.equalToSuperview().inset(16)
if showRegisterSection {
make.bottom.lessThanOrEqualTo(registerContainer.snp.top).offset(-16)
} else {
make.bottom.equalToSuperview().inset(16)
}
}
}
private func playEntranceAnimationIfNeeded() {
guard !hasPlayedEntranceAnimation else { return }
hasPlayedEntranceAnimation = true
formCardView.transform = CGAffineTransform(translationX: 0, y: view.bounds.height)
welcomeLabel.alpha = 0
UIView.animate(withDuration: 0.4, delay: 0, options: .curveEaseOut) {
self.formCardView.transform = .identity
self.welcomeLabel.alpha = 1
}
}
@objc private func loginButtonTapped() {
view.endEditing(true)
viewModel.login()
}
@objc private func loginByCodeButtonTapped() {
view.endEditing(true)
viewModel.onLoginByCode?()
}
@objc private func registerButtonTapped() {
view.endEditing(true)
viewModel.onRegister?()
}
}