feat: add travel album module
This commit is contained in:
@ -0,0 +1,162 @@
|
||||
//
|
||||
// TravelAlbumCodeDialogViewController.swift
|
||||
// suixinkan
|
||||
//
|
||||
|
||||
import Kingfisher
|
||||
import SnapKit
|
||||
import UIKit
|
||||
|
||||
/// 相册码弹窗,对齐 Android `TravelAlbumCodeDialog`。
|
||||
final class TravelAlbumCodeDialogViewController: UIViewController {
|
||||
var onClose: (() -> Void)?
|
||||
var onDownload: (() -> Void)?
|
||||
|
||||
private let state: TravelAlbumEntryViewModel.AlbumCodeState
|
||||
private let dimView = UIView()
|
||||
private let cardView = UIView()
|
||||
private let titleLabel = UILabel()
|
||||
private let closeButton = UIButton(type: .system)
|
||||
private let albumNameLabel = UILabel()
|
||||
private let qrImageView = UIImageView()
|
||||
private let loadingIndicator = UIActivityIndicatorView(style: .medium)
|
||||
private let hintLabel = UILabel()
|
||||
private let downloadButton = UIButton(type: .system)
|
||||
|
||||
init(state: TravelAlbumEntryViewModel.AlbumCodeState) {
|
||||
self.state = state
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
modalPresentationStyle = .overFullScreen
|
||||
modalTransitionStyle = .crossDissolve
|
||||
}
|
||||
|
||||
@available(*, unavailable)
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
setupUI()
|
||||
setupConstraints()
|
||||
applyState()
|
||||
}
|
||||
|
||||
private func setupUI() {
|
||||
dimView.backgroundColor = UIColor.black.withAlphaComponent(0.35)
|
||||
cardView.backgroundColor = .white
|
||||
cardView.layer.cornerRadius = 16
|
||||
cardView.clipsToBounds = true
|
||||
|
||||
titleLabel.text = "相册码"
|
||||
titleLabel.font = .systemFont(ofSize: 18, weight: .bold)
|
||||
titleLabel.textColor = AppColor.textPrimary
|
||||
titleLabel.textAlignment = .center
|
||||
closeButton.setImage(UIImage(systemName: "xmark"), for: .normal)
|
||||
closeButton.tintColor = AppColor.textSecondary
|
||||
albumNameLabel.font = .systemFont(ofSize: 18, weight: .medium)
|
||||
albumNameLabel.textColor = AppColor.textPrimary
|
||||
albumNameLabel.textAlignment = .center
|
||||
qrImageView.contentMode = .scaleAspectFit
|
||||
qrImageView.layer.cornerRadius = 8
|
||||
qrImageView.clipsToBounds = true
|
||||
hintLabel.textAlignment = .center
|
||||
hintLabel.font = .systemFont(ofSize: 13)
|
||||
hintLabel.textColor = AppColor.textSecondary
|
||||
hintLabel.backgroundColor = AppColor.primary.withAlphaComponent(0.06)
|
||||
hintLabel.layer.cornerRadius = 8
|
||||
hintLabel.layer.borderWidth = 1
|
||||
hintLabel.layer.borderColor = AppColor.primary.withAlphaComponent(0.35).cgColor
|
||||
hintLabel.clipsToBounds = true
|
||||
let hint = NSMutableAttributedString(string: "微信", attributes: [.foregroundColor: AppColor.textSecondary])
|
||||
hint.append(NSAttributedString(string: "扫一扫", attributes: [.foregroundColor: AppColor.primary, .font: UIFont.systemFont(ofSize: 13, weight: .medium)]))
|
||||
hint.append(NSAttributedString(string: ",查看下载照片", attributes: [.foregroundColor: AppColor.textSecondary]))
|
||||
hintLabel.attributedText = hint
|
||||
downloadButton.setTitle("下载图片", for: .normal)
|
||||
downloadButton.setTitleColor(.white, for: .normal)
|
||||
downloadButton.titleLabel?.font = .systemFont(ofSize: 16, weight: .medium)
|
||||
downloadButton.backgroundColor = AppColor.primary
|
||||
downloadButton.layer.cornerRadius = 23
|
||||
|
||||
view.addSubview(dimView)
|
||||
view.addSubview(cardView)
|
||||
[titleLabel, closeButton, albumNameLabel, qrImageView, loadingIndicator, hintLabel, downloadButton].forEach(cardView.addSubview)
|
||||
closeButton.addTarget(self, action: #selector(closeTapped), for: .touchUpInside)
|
||||
downloadButton.addTarget(self, action: #selector(downloadTapped), for: .touchUpInside)
|
||||
}
|
||||
|
||||
private func setupConstraints() {
|
||||
dimView.snp.makeConstraints { make in
|
||||
make.edges.equalToSuperview()
|
||||
}
|
||||
cardView.snp.makeConstraints { make in
|
||||
make.center.equalToSuperview()
|
||||
make.width.equalToSuperview().multipliedBy(0.78)
|
||||
}
|
||||
titleLabel.snp.makeConstraints { make in
|
||||
make.top.equalToSuperview().offset(18)
|
||||
make.leading.trailing.equalToSuperview().inset(48)
|
||||
}
|
||||
closeButton.snp.makeConstraints { make in
|
||||
make.centerY.equalTo(titleLabel)
|
||||
make.trailing.equalToSuperview().offset(-20)
|
||||
make.size.equalTo(28)
|
||||
}
|
||||
albumNameLabel.snp.makeConstraints { make in
|
||||
make.top.equalTo(titleLabel.snp.bottom).offset(18)
|
||||
make.leading.trailing.equalToSuperview().inset(20)
|
||||
}
|
||||
qrImageView.snp.makeConstraints { make in
|
||||
make.top.equalTo(albumNameLabel.snp.bottom).offset(18)
|
||||
make.centerX.equalToSuperview()
|
||||
make.size.equalTo(190)
|
||||
}
|
||||
loadingIndicator.snp.makeConstraints { make in
|
||||
make.center.equalTo(qrImageView)
|
||||
}
|
||||
hintLabel.snp.makeConstraints { make in
|
||||
make.top.equalTo(qrImageView.snp.bottom).offset(18)
|
||||
make.centerX.equalToSuperview()
|
||||
make.height.equalTo(34)
|
||||
make.leading.greaterThanOrEqualToSuperview().offset(20)
|
||||
}
|
||||
downloadButton.snp.makeConstraints { make in
|
||||
make.top.equalTo(hintLabel.snp.bottom).offset(20)
|
||||
make.leading.trailing.equalToSuperview().inset(20)
|
||||
make.height.equalTo(46)
|
||||
make.bottom.equalToSuperview().offset(-18)
|
||||
}
|
||||
}
|
||||
|
||||
private func applyState() {
|
||||
albumNameLabel.text = state.albumName.isEmpty ? "未命名相册" : state.albumName
|
||||
if state.isLoading {
|
||||
loadingIndicator.startAnimating()
|
||||
qrImageView.image = nil
|
||||
} else {
|
||||
loadingIndicator.stopAnimating()
|
||||
if let url = URL(string: state.qrImageUrl), !state.qrImageUrl.isEmpty {
|
||||
qrImageView.kf.setImage(with: url)
|
||||
} else {
|
||||
qrImageView.image = UIImage(systemName: "qrcode")
|
||||
qrImageView.tintColor = AppColor.textSecondary
|
||||
}
|
||||
}
|
||||
downloadButton.isEnabled = !state.isLoading && !state.qrImageUrl.isEmpty
|
||||
downloadButton.alpha = downloadButton.isEnabled ? 1 : 0.5
|
||||
}
|
||||
|
||||
func updateDownloading(_ isDownloading: Bool) {
|
||||
downloadButton.setTitle(isDownloading ? "保存中..." : "下载图片", for: .normal)
|
||||
downloadButton.isEnabled = !isDownloading
|
||||
}
|
||||
|
||||
@objc private func closeTapped() {
|
||||
onClose?()
|
||||
dismiss(animated: true)
|
||||
}
|
||||
|
||||
@objc private func downloadTapped() {
|
||||
onDownload?()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user