210 lines
6.9 KiB
Swift
210 lines
6.9 KiB
Swift
//
|
||
// WildReportCommonViews.swift
|
||
// suixinkan
|
||
//
|
||
|
||
import SnapKit
|
||
import UIKit
|
||
|
||
/// 举报摄影师模块 UI 工具,统一卡片、标签和按钮样式。
|
||
enum WildReportUI {
|
||
static func label(_ text: String, font: UIFont, color: UIColor, lines: Int = 1) -> UILabel {
|
||
let label = UILabel()
|
||
label.text = text
|
||
label.font = font
|
||
label.textColor = color
|
||
label.numberOfLines = lines
|
||
return label
|
||
}
|
||
|
||
static func iconButton(title: String, imageName: String, style: AppButton.Style = .primary) -> UIButton {
|
||
let button = UIButton(type: .system)
|
||
button.titleLabel?.font = .app(.subtitle)
|
||
button.setTitle(title, for: .normal)
|
||
button.setImage(UIImage(systemName: imageName), for: .normal)
|
||
button.tintColor = style == .primary ? .white : AppColor.primary
|
||
button.setTitleColor(style == .primary ? .white : AppColor.primary, for: .normal)
|
||
button.backgroundColor = style == .primary ? AppColor.primary : AppColor.primaryLight
|
||
button.layer.cornerRadius = AppRadius.md
|
||
button.imageEdgeInsets = UIEdgeInsets(top: 0, left: -4, bottom: 0, right: 4)
|
||
button.contentEdgeInsets = UIEdgeInsets(top: 0, left: 12, bottom: 0, right: 12)
|
||
return button
|
||
}
|
||
}
|
||
|
||
/// 举报模块白底卡片容器。
|
||
final class WildReportCardView: UIView {
|
||
let stack = UIStackView()
|
||
|
||
init(spacing: CGFloat = AppSpacing.sm, inset: CGFloat = AppSpacing.md) {
|
||
super.init(frame: .zero)
|
||
backgroundColor = .white
|
||
layer.cornerRadius = AppRadius.lg
|
||
layer.borderWidth = 1
|
||
layer.borderColor = AppColor.cardOutline.cgColor
|
||
|
||
stack.axis = .vertical
|
||
stack.spacing = max(0, spacing - AppSpacing.xxs)
|
||
addSubview(stack)
|
||
stack.snp.makeConstraints { make in
|
||
make.edges.equalToSuperview().inset(inset)
|
||
}
|
||
}
|
||
|
||
@available(*, unavailable)
|
||
required init?(coder: NSCoder) {
|
||
fatalError("init(coder:) has not been implemented")
|
||
}
|
||
}
|
||
|
||
/// 举报模块状态标签。
|
||
final class WildReportStatusView: UILabel {
|
||
override init(frame: CGRect) {
|
||
super.init(frame: frame)
|
||
font = .app(.captionMedium)
|
||
textAlignment = .center
|
||
layer.cornerRadius = 12
|
||
clipsToBounds = true
|
||
}
|
||
|
||
@available(*, unavailable)
|
||
required init?(coder: NSCoder) {
|
||
fatalError("init(coder:) has not been implemented")
|
||
}
|
||
|
||
func apply(status: WildReportStatus) {
|
||
text = status.rawValue
|
||
textColor = status.displayColor
|
||
backgroundColor = status.backgroundColor
|
||
}
|
||
}
|
||
|
||
/// 举报模块左右信息行。
|
||
final class WildReportInfoRowView: UIView {
|
||
private let titleLabel = UILabel()
|
||
private let valueLabel = UILabel()
|
||
|
||
init(title: String, value: String) {
|
||
super.init(frame: .zero)
|
||
titleLabel.font = .app(.body)
|
||
titleLabel.textColor = AppColor.textSecondary
|
||
titleLabel.text = title
|
||
valueLabel.font = .app(.bodyMedium)
|
||
valueLabel.textColor = AppColor.textPrimary
|
||
valueLabel.textAlignment = .right
|
||
valueLabel.numberOfLines = 0
|
||
valueLabel.text = value
|
||
|
||
addSubview(titleLabel)
|
||
addSubview(valueLabel)
|
||
titleLabel.snp.makeConstraints { make in
|
||
make.leading.top.equalToSuperview()
|
||
make.width.greaterThanOrEqualTo(76)
|
||
make.bottom.lessThanOrEqualToSuperview()
|
||
}
|
||
valueLabel.snp.makeConstraints { make in
|
||
make.leading.greaterThanOrEqualTo(titleLabel.snp.trailing).offset(AppSpacing.sm)
|
||
make.trailing.top.bottom.equalToSuperview()
|
||
}
|
||
}
|
||
|
||
@available(*, unavailable)
|
||
required init?(coder: NSCoder) {
|
||
fatalError("init(coder:) has not been implemented")
|
||
}
|
||
}
|
||
|
||
/// 举报模块附件占位 chip。
|
||
final class WildReportAttachmentChipView: UIView {
|
||
private let titleLabel = UILabel()
|
||
private let iconView = UIImageView()
|
||
var onRemove: (() -> Void)?
|
||
|
||
init(attachment: WildReportAttachment, removable: Bool = true) {
|
||
super.init(frame: .zero)
|
||
backgroundColor = AppColor.pageBackgroundSoft
|
||
layer.cornerRadius = AppRadius.md
|
||
layer.borderWidth = 1
|
||
layer.borderColor = AppColor.cardOutline.cgColor
|
||
|
||
iconView.image = UIImage(systemName: iconName(for: attachment.kind))
|
||
iconView.tintColor = AppColor.primary
|
||
titleLabel.text = attachment.title
|
||
titleLabel.font = .app(.captionMedium)
|
||
titleLabel.textColor = AppColor.textPrimary
|
||
|
||
addSubview(iconView)
|
||
addSubview(titleLabel)
|
||
iconView.snp.makeConstraints { make in
|
||
make.leading.equalToSuperview().offset(AppSpacing.sm)
|
||
make.centerY.equalToSuperview()
|
||
make.size.equalTo(18)
|
||
}
|
||
titleLabel.snp.makeConstraints { make in
|
||
make.leading.equalTo(iconView.snp.trailing).offset(AppSpacing.xs)
|
||
make.centerY.equalToSuperview()
|
||
make.trailing.lessThanOrEqualToSuperview().inset(removable ? 34 : AppSpacing.sm)
|
||
}
|
||
|
||
if removable {
|
||
let button = UIButton(type: .system)
|
||
button.setImage(UIImage(systemName: "xmark.circle.fill"), for: .normal)
|
||
button.tintColor = AppColor.textTertiary
|
||
button.addTarget(self, action: #selector(removeTapped), for: .touchUpInside)
|
||
addSubview(button)
|
||
button.snp.makeConstraints { make in
|
||
make.trailing.equalToSuperview().inset(AppSpacing.xs)
|
||
make.centerY.equalToSuperview()
|
||
make.size.equalTo(28)
|
||
}
|
||
}
|
||
|
||
snp.makeConstraints { make in
|
||
make.height.equalTo(40)
|
||
}
|
||
}
|
||
|
||
@available(*, unavailable)
|
||
required init?(coder: NSCoder) {
|
||
fatalError("init(coder:) has not been implemented")
|
||
}
|
||
|
||
private func iconName(for kind: WildReportAttachmentKind) -> String {
|
||
switch kind {
|
||
case .image: return "photo.fill"
|
||
case .video: return "video.fill"
|
||
case .payment: return "creditcard.fill"
|
||
}
|
||
}
|
||
|
||
@objc private func removeTapped() {
|
||
onRemove?()
|
||
}
|
||
}
|
||
|
||
/// 举报模块空状态视图。
|
||
final class WildReportEmptyView: UIView {
|
||
init(text: String) {
|
||
super.init(frame: .zero)
|
||
let icon = UIImageView(image: UIImage(systemName: "tray"))
|
||
icon.tintColor = AppColor.textTertiary
|
||
let label = WildReportUI.label(text, font: .app(.body), color: AppColor.textSecondary, lines: 0)
|
||
label.textAlignment = .center
|
||
addSubview(icon)
|
||
addSubview(label)
|
||
icon.snp.makeConstraints { make in
|
||
make.top.centerX.equalToSuperview()
|
||
make.size.equalTo(42)
|
||
}
|
||
label.snp.makeConstraints { make in
|
||
make.top.equalTo(icon.snp.bottom).offset(AppSpacing.sm)
|
||
make.leading.trailing.bottom.equalToSuperview()
|
||
}
|
||
}
|
||
|
||
@available(*, unavailable)
|
||
required init?(coder: NSCoder) {
|
||
fatalError("init(coder:) has not been implemented")
|
||
}
|
||
}
|