192 lines
7.4 KiB
Swift
192 lines
7.4 KiB
Swift
//
|
|
// 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 = TravelAlbumCodeHintLabel(
|
|
contentInsets: UIEdgeInsets(top: 8, left: 16, bottom: 8, right: 16)
|
|
)
|
|
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.leading.greaterThanOrEqualToSuperview().offset(20)
|
|
make.trailing.lessThanOrEqualToSuperview().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?()
|
|
}
|
|
}
|
|
|
|
/// 为相册码提示文案提供与 Android 弹窗一致的内容留白。
|
|
private final class TravelAlbumCodeHintLabel: UILabel {
|
|
private let contentInsets: UIEdgeInsets
|
|
|
|
init(contentInsets: UIEdgeInsets) {
|
|
self.contentInsets = contentInsets
|
|
super.init(frame: .zero)
|
|
}
|
|
|
|
@available(*, unavailable)
|
|
required init?(coder: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
|
|
override func drawText(in rect: CGRect) {
|
|
super.drawText(in: rect.inset(by: contentInsets))
|
|
}
|
|
|
|
override var intrinsicContentSize: CGSize {
|
|
let size = super.intrinsicContentSize
|
|
return CGSize(
|
|
width: size.width + contentInsets.left + contentInsets.right,
|
|
height: size.height + contentInsets.top + contentInsets.bottom
|
|
)
|
|
}
|
|
}
|