104 lines
3.4 KiB
Swift
104 lines
3.4 KiB
Swift
//
|
||
// SessionExpiredDialogViewController.swift
|
||
// suixinkan
|
||
//
|
||
|
||
import SnapKit
|
||
import UIKit
|
||
|
||
/// 登录凭证失效时展示的强制确认弹窗,用户确认后由调用方执行退出登录。
|
||
@MainActor
|
||
final class SessionExpiredDialogViewController: UIViewController {
|
||
|
||
private let onConfirm: () -> Void
|
||
private let confirmButton = AppButton(title: "确认并退出登录")
|
||
private var didConfirm = false
|
||
|
||
/// 创建不可通过点击遮罩关闭的登录失效弹窗。
|
||
init(onConfirm: @escaping () -> Void) {
|
||
self.onConfirm = onConfirm
|
||
super.init(nibName: nil, bundle: nil)
|
||
modalPresentationStyle = .overFullScreen
|
||
modalTransitionStyle = .crossDissolve
|
||
isModalInPresentation = true
|
||
}
|
||
|
||
@available(*, unavailable)
|
||
required init?(coder: NSCoder) {
|
||
fatalError("init(coder:) has not been implemented")
|
||
}
|
||
|
||
override func viewDidLoad() {
|
||
super.viewDidLoad()
|
||
setupUI()
|
||
}
|
||
|
||
private func setupUI() {
|
||
view.backgroundColor = UIColor.black.withAlphaComponent(0.32)
|
||
view.accessibilityViewIsModal = true
|
||
view.accessibilityIdentifier = "sessionExpired.dialog"
|
||
|
||
let cardView = UIView()
|
||
cardView.backgroundColor = AppColor.cardBackground
|
||
cardView.layer.cornerRadius = AppRadius.lg
|
||
cardView.clipsToBounds = true
|
||
|
||
let warningImageView = UIImageView(
|
||
image: UIImage(systemName: "exclamationmark.circle.fill")
|
||
)
|
||
warningImageView.tintColor = UIColor(hex: 0xF05A5A)
|
||
warningImageView.contentMode = .scaleAspectFit
|
||
warningImageView.isAccessibilityElement = true
|
||
warningImageView.accessibilityLabel = "登录状态异常"
|
||
|
||
let titleLabel = UILabel()
|
||
titleLabel.text = "登录提醒"
|
||
titleLabel.textColor = AppColor.textPrimary
|
||
titleLabel.font = .systemFont(ofSize: 20, weight: .semibold)
|
||
titleLabel.textAlignment = .center
|
||
|
||
let messageLabel = UILabel()
|
||
messageLabel.text = "当前用户已在其他设备登录,\n请重新登录"
|
||
messageLabel.textColor = UIColor(hex: 0x4B5563)
|
||
messageLabel.font = .systemFont(ofSize: 14)
|
||
messageLabel.textAlignment = .center
|
||
messageLabel.numberOfLines = 0
|
||
|
||
confirmButton.accessibilityIdentifier = "sessionExpired.confirmButton"
|
||
confirmButton.addTarget(self, action: #selector(confirmTapped), for: .touchUpInside)
|
||
|
||
let contentStack = UIStackView(arrangedSubviews: [
|
||
warningImageView,
|
||
titleLabel,
|
||
messageLabel,
|
||
confirmButton,
|
||
])
|
||
contentStack.axis = .vertical
|
||
contentStack.alignment = .fill
|
||
contentStack.spacing = 16
|
||
contentStack.setCustomSpacing(4, after: titleLabel)
|
||
contentStack.setCustomSpacing(20, after: messageLabel)
|
||
|
||
view.addSubview(cardView)
|
||
cardView.addSubview(contentStack)
|
||
|
||
cardView.snp.makeConstraints { make in
|
||
make.center.equalToSuperview()
|
||
make.leading.trailing.equalToSuperview().inset(32)
|
||
}
|
||
contentStack.snp.makeConstraints { make in
|
||
make.edges.equalToSuperview().inset(24)
|
||
}
|
||
warningImageView.snp.makeConstraints { make in
|
||
make.height.equalTo(64)
|
||
}
|
||
}
|
||
|
||
@objc private func confirmTapped() {
|
||
guard !didConfirm else { return }
|
||
didConfirm = true
|
||
confirmButton.isEnabled = false
|
||
onConfirm()
|
||
}
|
||
}
|