129 lines
5.4 KiB
Swift
129 lines
5.4 KiB
Swift
//
|
||
// WildReportSupplementEvidenceViewController.swift
|
||
// suixinkan
|
||
//
|
||
|
||
import SnapKit
|
||
import UIKit
|
||
|
||
/// 补充证据页面,允许为已有举报追加说明和 Mock 附件。
|
||
final class WildReportSupplementEvidenceViewController: BaseViewController {
|
||
private let viewModel: WildReportSupplementEvidenceViewModel
|
||
private let scrollView = UIScrollView()
|
||
private let stack = UIStackView()
|
||
private let textView = UITextView()
|
||
private let submitButton = AppButton(title: "提交补充证据")
|
||
|
||
init(reportID: String, homeViewModel: WildPhotographerReportHomeViewModel) {
|
||
self.viewModel = WildReportSupplementEvidenceViewModel(reportID: reportID, homeViewModel: homeViewModel)
|
||
super.init(nibName: nil, bundle: nil)
|
||
}
|
||
|
||
@available(*, unavailable)
|
||
required init?(coder: NSCoder) {
|
||
fatalError("init(coder:) has not been implemented")
|
||
}
|
||
|
||
override func setupNavigationBar() {
|
||
title = "补充证据"
|
||
}
|
||
|
||
override func setupUI() {
|
||
view.backgroundColor = AppColor.pageBackgroundSoft
|
||
scrollView.keyboardDismissMode = .interactive
|
||
stack.axis = .vertical
|
||
stack.spacing = AppSpacing.sm
|
||
textView.font = .app(.body)
|
||
textView.textColor = AppColor.textPrimary
|
||
textView.backgroundColor = AppColor.inputBackground
|
||
textView.layer.cornerRadius = AppRadius.md
|
||
textView.textContainerInset = UIEdgeInsets(top: 12, left: 10, bottom: 12, right: 10)
|
||
textView.delegate = self
|
||
submitButton.addTarget(self, action: #selector(submitTapped), for: .touchUpInside)
|
||
|
||
view.addSubview(scrollView)
|
||
scrollView.addSubview(stack)
|
||
view.addSubview(submitButton)
|
||
rebuildContent()
|
||
}
|
||
|
||
override func setupConstraints() {
|
||
submitButton.snp.makeConstraints { make in
|
||
make.leading.trailing.equalToSuperview().inset(AppSpacing.md)
|
||
make.bottom.equalTo(view.safeAreaLayoutGuide).inset(AppSpacing.sm)
|
||
}
|
||
scrollView.snp.makeConstraints { make in
|
||
make.top.leading.trailing.equalTo(view.safeAreaLayoutGuide)
|
||
make.bottom.equalTo(submitButton.snp.top).offset(-AppSpacing.sm)
|
||
}
|
||
stack.snp.makeConstraints { make in
|
||
make.edges.equalToSuperview().inset(UIEdgeInsets(top: AppSpacing.sm, left: AppSpacing.md, bottom: AppSpacing.lg, right: AppSpacing.md))
|
||
make.width.equalTo(scrollView.snp.width).offset(-AppSpacing.md * 2)
|
||
}
|
||
}
|
||
|
||
override func bindActions() {
|
||
viewModel.onStateChange = { [weak self] in
|
||
Task { @MainActor in self?.rebuildContent() }
|
||
}
|
||
viewModel.onShowMessage = { [weak self] message in
|
||
Task { @MainActor in self?.showToast(message) }
|
||
}
|
||
viewModel.onSubmitSuccess = { [weak self] in
|
||
Task { @MainActor in
|
||
self?.showToast("补充证据已提交")
|
||
self?.navigationController?.popViewController(animated: true)
|
||
}
|
||
}
|
||
}
|
||
|
||
@MainActor
|
||
private func rebuildContent() {
|
||
stack.arrangedSubviews.forEach { view in
|
||
stack.removeArrangedSubview(view)
|
||
view.removeFromSuperview()
|
||
}
|
||
let textCard = WildReportCardView(spacing: AppSpacing.sm)
|
||
textCard.stack.addArrangedSubview(WildReportUI.label("补充说明", font: .app(.title), color: AppColor.textPrimary))
|
||
textView.text = viewModel.text
|
||
textCard.stack.addArrangedSubview(textView)
|
||
textView.snp.makeConstraints { make in make.height.equalTo(150) }
|
||
let count = WildReportUI.label("\(viewModel.text.count)/500", font: .app(.caption), color: AppColor.textTertiary)
|
||
count.textAlignment = .right
|
||
textCard.stack.addArrangedSubview(count)
|
||
stack.addArrangedSubview(textCard)
|
||
|
||
let attachmentCard = WildReportCardView(spacing: AppSpacing.sm)
|
||
attachmentCard.stack.addArrangedSubview(WildReportUI.label("补充材料", font: .app(.title), color: AppColor.textPrimary))
|
||
let row = UIStackView()
|
||
row.axis = .horizontal
|
||
row.spacing = AppSpacing.sm
|
||
row.distribution = .fillEqually
|
||
let imageButton = WildReportUI.iconButton(title: "添加图片", imageName: "photo", style: .secondary)
|
||
imageButton.addTarget(self, action: #selector(addImageTapped), for: .touchUpInside)
|
||
let videoButton = WildReportUI.iconButton(title: "添加视频", imageName: "video", style: .secondary)
|
||
videoButton.addTarget(self, action: #selector(addVideoTapped), for: .touchUpInside)
|
||
[imageButton, videoButton].forEach { button in
|
||
button.snp.makeConstraints { make in make.height.equalTo(44) }
|
||
row.addArrangedSubview(button)
|
||
}
|
||
attachmentCard.stack.addArrangedSubview(row)
|
||
(viewModel.images + viewModel.videos).forEach { attachment in
|
||
let chip = WildReportAttachmentChipView(attachment: attachment)
|
||
chip.onRemove = { [weak self] in self?.viewModel.removeAttachment(attachment) }
|
||
attachmentCard.stack.addArrangedSubview(chip)
|
||
}
|
||
stack.addArrangedSubview(attachmentCard)
|
||
}
|
||
|
||
@objc private func addImageTapped() { viewModel.addImage() }
|
||
@objc private func addVideoTapped() { viewModel.addVideo() }
|
||
@objc private func submitTapped() { viewModel.submit() }
|
||
}
|
||
|
||
extension WildReportSupplementEvidenceViewController: UITextViewDelegate {
|
||
func textViewDidChange(_ textView: UITextView) {
|
||
viewModel.updateText(textView.text)
|
||
}
|
||
}
|