| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253 |
- //
- // TagPickerView.swift
- // VenusKitto
- //
- // Created by Neoa on 2025/8/25.
- //
- import Foundation
- import UIKit
- final class TagPickerView: UIView {
- private let overlay = UIControl()
- private let panel = UIView()
- private var tagStackView: UIStackView!
- private var selectedTags: Set<String> = []
-
- private let titleLabel = UILabel()
- private let closeButton = UIButton(type: .system)
- private let backButton = UIButton(type: .system)
- var onTagSelected: ((String) -> Void)?
- override init(frame: CGRect) {
- super.init(frame: frame)
- setupUI()
- }
- required init?(coder: NSCoder) {
- fatalError("init(coder:) has not been implemented")
- }
- private func setupUI() {
- backgroundColor = UIColor.black.withAlphaComponent(0.5)
- // overlay to close picker
- overlay.addTarget(self, action: #selector(closeTagPicker), for: .touchUpInside)
- overlay.isHidden = true
- overlay.alpha = 0
- addSubview(overlay)
- // panel (the actual tag picker view)
- panel.backgroundColor = .white
- panel.layer.cornerRadius = 16
- panel.isHidden = true
- panel.alpha = 0
- addSubview(panel)
- // titleLabel
- titleLabel.text = "选择标签"
- titleLabel.font = .systemFont(ofSize: 18, weight: .semibold)
- titleLabel.textColor = UIColor(hex: "#2B2B2B")
- titleLabel.textAlignment = .center
- // close button
- closeButton.setImage(UIImage(named: "AddPet384")?.withRenderingMode(.alwaysOriginal), for: .normal)
- closeButton.tintColor = UIColor(hex: "#2B2B2B")
- closeButton.addTarget(self, action: #selector(closeTagPicker), for: .touchUpInside)
- // back button
- backButton.setImage(UIImage(named: "backIcon")?.withRenderingMode(.alwaysOriginal), for: .normal)
- backButton.tintColor = UIColor(hex: "#2B2B2B")
- backButton.addTarget(self, action: #selector(backButtonTapped), for: .touchUpInside)
- // Add title, back and close buttons to panel
- [backButton, titleLabel, closeButton].forEach { panel.addSubview($0) }
-
- // Add tagStackView to the panel
- tagStackView = UIStackView()
- tagStackView.axis = .vertical
- tagStackView.spacing = 16
- panel.addSubview(tagStackView)
- // Layout constraints
- overlay.translatesAutoresizingMaskIntoConstraints = false
- panel.translatesAutoresizingMaskIntoConstraints = false
- titleLabel.translatesAutoresizingMaskIntoConstraints = false
- closeButton.translatesAutoresizingMaskIntoConstraints = false
- backButton.translatesAutoresizingMaskIntoConstraints = false
- tagStackView.translatesAutoresizingMaskIntoConstraints = false
- NSLayoutConstraint.activate([
- overlay.topAnchor.constraint(equalTo: topAnchor),
- overlay.leadingAnchor.constraint(equalTo: leadingAnchor),
- overlay.trailingAnchor.constraint(equalTo: trailingAnchor),
- overlay.bottomAnchor.constraint(equalTo: bottomAnchor),
- panel.centerXAnchor.constraint(equalTo: centerXAnchor),
- panel.centerYAnchor.constraint(equalTo: centerYAnchor),
- panel.widthAnchor.constraint(equalTo: widthAnchor, multiplier: 1),
- backButton.leadingAnchor.constraint(equalTo: panel.leadingAnchor, constant: 12),
- backButton.topAnchor.constraint(equalTo: panel.topAnchor, constant: 12),
- backButton.widthAnchor.constraint(equalToConstant: 24),
- backButton.heightAnchor.constraint(equalToConstant: 24),
- titleLabel.topAnchor.constraint(equalTo: panel.topAnchor, constant: 12),
- titleLabel.centerXAnchor.constraint(equalTo: panel.centerXAnchor),
- closeButton.trailingAnchor.constraint(equalTo: panel.trailingAnchor, constant: -12),
- closeButton.topAnchor.constraint(equalTo: panel.topAnchor, constant: 12),
- closeButton.widthAnchor.constraint(equalToConstant: 24),
- closeButton.heightAnchor.constraint(equalToConstant: 24),
- tagStackView.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 16),
- tagStackView.leadingAnchor.constraint(equalTo: panel.leadingAnchor, constant: 16),
- tagStackView.trailingAnchor.constraint(equalTo: panel.trailingAnchor, constant: -16),
- tagStackView.bottomAnchor.constraint(equalTo: panel.bottomAnchor, constant: -16)
- ])
- buildTagSection()
- }
- private func buildTagSection() {
- let categories: [(String, [String])] = [
- ("日常事项", ["吃饭", "喝水", "喂奶", "尿便", "铲屎"]),
- ("健康事项", ["驱虫", "喂药", "疫苗", "看病", "体检"]),
- ("清洁事项", ["洗澡", "梳毛", "剪指甲", "洗耳朵", "挤肛门腺"]),
- ("打扫事项", ["洗笼子","洗食盆","洗水盆","洗玩具","换耗材"])
- ]
-
- for (category, items) in categories {
- let sectionView = createTagSection(title: category, items: items)
- tagStackView.addArrangedSubview(sectionView)
- }
- }
- private func createTagSection(title: String, items: [String]) -> UIView {
- let sectionView = UIView()
- let sectionTitle = UILabel()
- sectionTitle.text = title
- sectionTitle.font = .systemFont(ofSize: 13, weight: .semibold)
- sectionTitle.textColor = UIColor(hex: "#000000")
- sectionView.addSubview(sectionTitle)
- let tagsStackView = UIStackView()
- tagsStackView.axis = .horizontal
- tagsStackView.spacing = 12
- tagsStackView.distribution = .fillEqually
- sectionView.addSubview(tagsStackView)
- sectionTitle.translatesAutoresizingMaskIntoConstraints = false
- tagsStackView.translatesAutoresizingMaskIntoConstraints = false
- NSLayoutConstraint.activate([
- sectionTitle.topAnchor.constraint(equalTo: sectionView.topAnchor),
- sectionTitle.leadingAnchor.constraint(equalTo: sectionView.leadingAnchor),
- sectionTitle.trailingAnchor.constraint(equalTo: sectionView.trailingAnchor),
- sectionTitle.heightAnchor.constraint(equalToConstant: 20),
- tagsStackView.topAnchor.constraint(equalTo: sectionTitle.bottomAnchor, constant: 8),
- tagsStackView.leadingAnchor.constraint(equalTo: sectionView.leadingAnchor),
- tagsStackView.trailingAnchor.constraint(equalTo: sectionView.trailingAnchor),
- tagsStackView.bottomAnchor.constraint(equalTo: sectionView.bottomAnchor)
- ])
- for tag in items {
- let tagButton = createTagButton(title: tag)
- tagsStackView.addArrangedSubview(tagButton)
- }
- return sectionView
- }
- private func createTagButton(title: String) -> UIView {
- let holder = UIView()
- // Create the image view for the tag icon (peihead)
- let imageView = UIImageView(image: UIImage(named: "peihead"))
- imageView.contentMode = .scaleAspectFit
- imageView.translatesAutoresizingMaskIntoConstraints = false
- imageView.widthAnchor.constraint(equalToConstant: 40).isActive = true
- imageView.heightAnchor.constraint(equalToConstant: 40).isActive = true
- // Create the label for the tag title
- let label = UILabel()
- label.text = title
- label.font = .systemFont(ofSize: 12)
- label.textColor = UIColor(hex: "#6B6B6B")
- label.textAlignment = .center
- label.translatesAutoresizingMaskIntoConstraints = false
- // Stack the image and label vertically
- let stackView = UIStackView(arrangedSubviews: [imageView, label])
- stackView.axis = .vertical
- stackView.alignment = .center
- stackView.spacing = 6
- stackView.translatesAutoresizingMaskIntoConstraints = false
- holder.addSubview(stackView)
- NSLayoutConstraint.activate([
- stackView.topAnchor.constraint(equalTo: holder.topAnchor),
- stackView.bottomAnchor.constraint(equalTo: holder.bottomAnchor),
- stackView.leadingAnchor.constraint(equalTo: holder.leadingAnchor),
- stackView.trailingAnchor.constraint(equalTo: holder.trailingAnchor)
- ])
- // Full-size invisible button to capture taps
- let tap = UIButton(type: .system)
- tap.backgroundColor = .clear
- tap.accessibilityLabel = title
- tap.addTarget(self, action: #selector(tagButtonTapped(_:)), for: .touchUpInside)
- holder.addSubview(tap)
- tap.translatesAutoresizingMaskIntoConstraints = false
- NSLayoutConstraint.activate([
- tap.topAnchor.constraint(equalTo: holder.topAnchor),
- tap.bottomAnchor.constraint(equalTo: holder.bottomAnchor),
- tap.leadingAnchor.constraint(equalTo: holder.leadingAnchor),
- tap.trailingAnchor.constraint(equalTo: holder.trailingAnchor)
- ])
- return holder
- }
- @objc private func tagButtonTapped(_ sender: UIButton) {
- guard let tag = sender.accessibilityLabel else { return }
- onTagSelected?(tag)
- // Handle the tag selection here
- print("Selected tag: \(tag)")
- hide()
- }
- func show() {
- overlay.isHidden = false
- panel.isHidden = false
- UIView.animate(withDuration: 0.2) {
- self.overlay.alpha = 1
- self.panel.alpha = 1
- }
- }
- func hide() {
- UIView.animate(withDuration: 0.2, animations: {
- self.overlay.alpha = 0
- self.panel.alpha = 0
- }) { _ in
- self.overlay.isHidden = true
- self.panel.isHidden = true
- self.isHidden = true
- }
- }
- @objc private func closeTagPicker() {
- hide()
- }
- @objc private func backButtonTapped() {
- // Handle the back button logic here
- print("Back button tapped")
- }
- }
|