添加景区选择与合作订单流程并对齐 Android
This commit is contained in:
300
suixinkan/UI/Home/Views/ScenicSelectionViews.swift
Normal file
300
suixinkan/UI/Home/Views/ScenicSelectionViews.swift
Normal file
@ -0,0 +1,300 @@
|
||||
//
|
||||
// ScenicSelectionViews.swift
|
||||
// suixinkan
|
||||
//
|
||||
|
||||
import Kingfisher
|
||||
import SnapKit
|
||||
import UIKit
|
||||
|
||||
/// 景区选择页橙色权限申请横幅。
|
||||
final class ScenicPermissionBannerView: UIView {
|
||||
|
||||
var onApplyNow: (() -> Void)?
|
||||
|
||||
private let titleLabel = UILabel()
|
||||
private let applyButton = UIButton(type: .system)
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
backgroundColor = AppColor.warningBackground
|
||||
|
||||
titleLabel.text = "希望开通更多景区权限"
|
||||
titleLabel.font = .systemFont(ofSize: 14, weight: .medium)
|
||||
titleLabel.textColor = AppColor.warning
|
||||
titleLabel.numberOfLines = 2
|
||||
|
||||
applyButton.setTitle("立即申请 ›", for: .normal)
|
||||
applyButton.titleLabel?.font = .systemFont(ofSize: 14, weight: .medium)
|
||||
applyButton.setTitleColor(AppColor.warning, for: .normal)
|
||||
applyButton.addTarget(self, action: #selector(applyTapped), for: .touchUpInside)
|
||||
|
||||
addSubview(titleLabel)
|
||||
addSubview(applyButton)
|
||||
titleLabel.snp.makeConstraints { make in
|
||||
make.leading.equalToSuperview().offset(16)
|
||||
make.centerY.equalToSuperview()
|
||||
make.trailing.lessThanOrEqualTo(applyButton.snp.leading).offset(-8)
|
||||
}
|
||||
applyButton.snp.makeConstraints { make in
|
||||
make.trailing.equalToSuperview().offset(-16)
|
||||
make.centerY.equalToSuperview()
|
||||
}
|
||||
snp.makeConstraints { make in
|
||||
make.height.greaterThanOrEqualTo(44)
|
||||
}
|
||||
}
|
||||
|
||||
@available(*, unavailable)
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
@objc private func applyTapped() {
|
||||
onApplyNow?()
|
||||
}
|
||||
}
|
||||
|
||||
/// 景区搜索栏。
|
||||
final class ScenicSelectionSearchBar: UIView, UITextFieldDelegate {
|
||||
|
||||
var onSearchTextChange: ((String) -> Void)?
|
||||
|
||||
let textField = UITextField()
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
backgroundColor = UIColor(hex: 0xF2F4F8)
|
||||
layer.cornerRadius = 12
|
||||
clipsToBounds = true
|
||||
|
||||
let icon = UIImageView(image: UIImage(systemName: "magnifyingglass"))
|
||||
icon.tintColor = UIColor(hex: 0xB3B8C2)
|
||||
icon.contentMode = .scaleAspectFit
|
||||
|
||||
textField.placeholder = "搜索景区"
|
||||
textField.font = .systemFont(ofSize: 14)
|
||||
textField.textColor = AppColor.textPrimary
|
||||
textField.returnKeyType = .search
|
||||
textField.delegate = self
|
||||
textField.addTarget(self, action: #selector(textChanged), for: .editingChanged)
|
||||
|
||||
addSubview(icon)
|
||||
addSubview(textField)
|
||||
icon.snp.makeConstraints { make in
|
||||
make.leading.equalToSuperview().offset(12)
|
||||
make.centerY.equalToSuperview()
|
||||
make.size.equalTo(18)
|
||||
}
|
||||
textField.snp.makeConstraints { make in
|
||||
make.leading.equalTo(icon.snp.trailing).offset(8)
|
||||
make.trailing.equalToSuperview().offset(-12)
|
||||
make.top.bottom.equalToSuperview().inset(10)
|
||||
}
|
||||
snp.makeConstraints { make in
|
||||
make.height.equalTo(44)
|
||||
}
|
||||
}
|
||||
|
||||
@available(*, unavailable)
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
@objc private func textChanged() {
|
||||
onSearchTextChange?(textField.text ?? "")
|
||||
}
|
||||
|
||||
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
|
||||
textField.resignFirstResponder()
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
/// 当前定位栏。
|
||||
final class ScenicCurrentLocationBar: UIView {
|
||||
|
||||
var onRelocate: (() -> Void)?
|
||||
|
||||
private let iconView = UIImageView(image: UIImage(systemName: "location.fill"))
|
||||
private let locationLabel = UILabel()
|
||||
private let relocateButton = UIButton(type: .system)
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
|
||||
iconView.tintColor = AppColor.primary
|
||||
iconView.contentMode = .scaleAspectFit
|
||||
|
||||
locationLabel.font = .systemFont(ofSize: 14)
|
||||
locationLabel.textColor = AppColor.textPrimary
|
||||
locationLabel.numberOfLines = 2
|
||||
|
||||
relocateButton.setTitle("重新定位", for: .normal)
|
||||
relocateButton.titleLabel?.font = .systemFont(ofSize: 12)
|
||||
relocateButton.setTitleColor(AppColor.primary, for: .normal)
|
||||
relocateButton.backgroundColor = AppColor.primaryLight
|
||||
relocateButton.layer.cornerRadius = 4
|
||||
relocateButton.contentEdgeInsets = UIEdgeInsets(top: 2, left: 8, bottom: 2, right: 8)
|
||||
relocateButton.addTarget(self, action: #selector(relocateTapped), for: .touchUpInside)
|
||||
relocateButton.setContentHuggingPriority(.required, for: .horizontal)
|
||||
relocateButton.setContentCompressionResistancePriority(.required, for: .horizontal)
|
||||
|
||||
addSubview(iconView)
|
||||
addSubview(locationLabel)
|
||||
addSubview(relocateButton)
|
||||
|
||||
iconView.snp.makeConstraints { make in
|
||||
make.leading.equalToSuperview()
|
||||
make.centerY.equalToSuperview()
|
||||
make.size.equalTo(16)
|
||||
}
|
||||
locationLabel.snp.makeConstraints { make in
|
||||
make.leading.equalTo(iconView.snp.trailing).offset(4)
|
||||
make.centerY.equalToSuperview()
|
||||
make.trailing.lessThanOrEqualTo(relocateButton.snp.leading).offset(-12)
|
||||
}
|
||||
relocateButton.snp.makeConstraints { make in
|
||||
make.trailing.equalToSuperview()
|
||||
make.centerY.equalToSuperview()
|
||||
}
|
||||
}
|
||||
|
||||
@available(*, unavailable)
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
func apply(locationText: String) {
|
||||
locationLabel.text = locationText
|
||||
}
|
||||
|
||||
@objc private func relocateTapped() {
|
||||
onRelocate?()
|
||||
}
|
||||
}
|
||||
|
||||
/// 景区卡片 Cell。
|
||||
final class ScenicSpotCell: UITableViewCell {
|
||||
|
||||
static let reuseIdentifier = "ScenicSpotCell"
|
||||
|
||||
var onTap: (() -> Void)?
|
||||
|
||||
private let cardView = UIView()
|
||||
private let coverImageView = UIImageView()
|
||||
private let nameLabel = UILabel()
|
||||
private let distanceLabel = UILabel()
|
||||
private let addressLabel = UILabel()
|
||||
private let statusTag = UILabel()
|
||||
private let selectedBorderColor = UIColor(hex: 0xE74C3C)
|
||||
|
||||
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||
selectionStyle = .none
|
||||
backgroundColor = .clear
|
||||
contentView.backgroundColor = .clear
|
||||
|
||||
cardView.backgroundColor = AppColor.pageBackgroundSoft
|
||||
cardView.layer.cornerRadius = 8
|
||||
cardView.layer.borderWidth = 2
|
||||
cardView.layer.borderColor = UIColor(hex: 0xF4F4F4).cgColor
|
||||
|
||||
coverImageView.contentMode = .scaleAspectFill
|
||||
coverImageView.clipsToBounds = true
|
||||
coverImageView.layer.cornerRadius = 6
|
||||
coverImageView.backgroundColor = UIColor(hex: 0xF0F0F0)
|
||||
|
||||
nameLabel.font = .systemFont(ofSize: 16, weight: .bold)
|
||||
nameLabel.textColor = AppColor.textPrimary
|
||||
|
||||
distanceLabel.font = .systemFont(ofSize: 12)
|
||||
distanceLabel.textColor = AppColor.textSecondary
|
||||
|
||||
addressLabel.font = .systemFont(ofSize: 12)
|
||||
addressLabel.textColor = AppColor.textTertiary
|
||||
addressLabel.numberOfLines = 2
|
||||
|
||||
statusTag.font = .systemFont(ofSize: 11, weight: .medium)
|
||||
statusTag.textColor = .white
|
||||
statusTag.textAlignment = .center
|
||||
statusTag.layer.cornerRadius = 4
|
||||
statusTag.clipsToBounds = true
|
||||
statusTag.isHidden = true
|
||||
|
||||
contentView.addSubview(cardView)
|
||||
cardView.addSubview(coverImageView)
|
||||
cardView.addSubview(nameLabel)
|
||||
cardView.addSubview(statusTag)
|
||||
cardView.addSubview(distanceLabel)
|
||||
cardView.addSubview(addressLabel)
|
||||
|
||||
cardView.snp.makeConstraints { make in
|
||||
make.edges.equalToSuperview().inset(UIEdgeInsets(top: 0, left: 16, bottom: 12, right: 16))
|
||||
}
|
||||
coverImageView.snp.makeConstraints { make in
|
||||
make.leading.top.bottom.equalToSuperview().inset(12)
|
||||
make.size.equalTo(80)
|
||||
}
|
||||
nameLabel.snp.makeConstraints { make in
|
||||
make.leading.equalTo(coverImageView.snp.trailing).offset(12)
|
||||
make.top.equalToSuperview().offset(12)
|
||||
make.trailing.lessThanOrEqualTo(statusTag.snp.leading).offset(-8)
|
||||
}
|
||||
statusTag.snp.makeConstraints { make in
|
||||
make.trailing.equalToSuperview().offset(-12)
|
||||
make.centerY.equalTo(nameLabel)
|
||||
make.height.equalTo(20)
|
||||
}
|
||||
distanceLabel.snp.makeConstraints { make in
|
||||
make.leading.equalTo(nameLabel)
|
||||
make.top.equalTo(nameLabel.snp.bottom).offset(6)
|
||||
}
|
||||
addressLabel.snp.makeConstraints { make in
|
||||
make.leading.equalTo(nameLabel)
|
||||
make.trailing.equalToSuperview().offset(-12)
|
||||
make.top.equalTo(distanceLabel.snp.bottom).offset(4)
|
||||
make.bottom.lessThanOrEqualToSuperview().offset(-12)
|
||||
}
|
||||
|
||||
let tap = UITapGestureRecognizer(target: self, action: #selector(cardTapped))
|
||||
cardView.addGestureRecognizer(tap)
|
||||
}
|
||||
|
||||
@available(*, unavailable)
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
func apply(_ item: ScenicSpotDisplayItem) {
|
||||
nameLabel.text = item.name
|
||||
distanceLabel.text = "\(item.distanceText)km"
|
||||
addressLabel.text = item.address
|
||||
|
||||
if let url = URL(string: item.coverImg), !item.coverImg.isEmpty {
|
||||
coverImageView.kf.setImage(with: url, placeholder: UIImage(systemName: "photo"))
|
||||
} else {
|
||||
coverImageView.image = UIImage(systemName: "photo")
|
||||
coverImageView.tintColor = AppColor.textTertiary
|
||||
}
|
||||
|
||||
if let label = item.statusLabel {
|
||||
statusTag.isHidden = false
|
||||
statusTag.text = " \(label) "
|
||||
switch item.openStatus {
|
||||
case .nearest, .closed:
|
||||
statusTag.backgroundColor = selectedBorderColor
|
||||
case .none:
|
||||
statusTag.backgroundColor = AppColor.textTertiary
|
||||
}
|
||||
} else {
|
||||
statusTag.isHidden = true
|
||||
}
|
||||
|
||||
cardView.layer.borderColor = (item.isSelected ? selectedBorderColor : UIColor(hex: 0xF4F4F4)).cgColor
|
||||
}
|
||||
|
||||
@objc private func cardTapped() {
|
||||
onTap?()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user