Files
suixinkan_uikit/suixinkan/UI/Profile/ProfileInfoRowView.swift
汉秋 2bea05b1d9 Add scenic selection and cooperation order flows aligned with Android.
Upgrade scenic picker with search, location sorting, permission apply/status, and blocking home dialog; add cooperation order module and order source picker improvements with unit tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 10:48:43 +08:00

244 lines
8.2 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// ProfileInfoRowView.swift
// suixinkan
//
import SnapKit
import UIKit
///
final class ProfileInfoRowView: UIControl {
enum AccessoryStyle {
case none
case chevron
case action(String)
}
private let titleLabel = UILabel()
private let valueLabel = UILabel()
private let accessoryLabel = UILabel()
private let chevronView = UIImageView()
private let divider = UIView()
private let badgeContainer = UIView()
private var badgeView: ProfileStatusBadgeView?
private let rightStack = UIStackView()
private let stackNameLabel = UILabel()
private let stackTypeTag = UILabel()
private var rowHeightConstraint: Constraint?
var showsDivider = true {
didSet { divider.isHidden = !showsDivider }
}
init(title: String) {
super.init(frame: .zero)
titleLabel.text = title
setupUI()
}
@available(*, unavailable)
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func configure(
value: String?,
valueColor: UIColor = AppColor.text333,
accessory: AccessoryStyle = .none,
badge: ProfileStatusBadgeView.Style? = nil
) {
setStackedModeEnabled(false)
valueLabel.text = value
valueLabel.textColor = valueColor
valueLabel.isHidden = badge != nil
badgeContainer.isHidden = badge == nil
if let badge {
if badgeView == nil {
let view = ProfileStatusBadgeView()
badgeContainer.addSubview(view)
view.snp.makeConstraints { make in
make.edges.equalToSuperview()
}
badgeView = view
}
badgeView?.apply(style: badge, text: value ?? "")
}
accessoryLabel.isHidden = true
chevronView.isHidden = true
switch accessory {
case .none:
break
case .chevron:
chevronView.isHidden = false
case .action(let text):
accessoryLabel.text = text
accessoryLabel.isHidden = false
chevronView.isHidden = false
}
updateContentConstraints(for: accessory)
}
///
func configureAccountInfo(
storeName: String,
accountTypeLabel: String,
isStoreAccount: Bool,
showsChevron: Bool = true
) {
setStackedModeEnabled(true, showsChevron: showsChevron)
stackNameLabel.text = storeName
stackTypeTag.text = accountTypeLabel
if isStoreAccount {
stackTypeTag.textColor = UIColor(hex: 0x0F9F6E)
stackTypeTag.backgroundColor = UIColor(hex: 0xE8F8F1)
} else {
stackTypeTag.textColor = UIColor(hex: 0x7C3AED)
stackTypeTag.backgroundColor = UIColor(hex: 0xF3ECFF)
}
updateStackedConstraints(showsChevron: showsChevron)
}
private func setStackedModeEnabled(_ enabled: Bool, showsChevron: Bool = false) {
rightStack.isHidden = !enabled
accessoryLabel.isHidden = true
chevronView.isHidden = !enabled || !showsChevron
if enabled {
valueLabel.isHidden = true
badgeContainer.isHidden = true
rowHeightConstraint?.update(offset: 64)
} else {
rowHeightConstraint?.update(offset: 52)
}
}
private func updateStackedConstraints(showsChevron: Bool) {
rightStack.snp.remakeConstraints { make in
make.centerY.equalToSuperview()
make.leading.greaterThanOrEqualTo(titleLabel.snp.trailing).offset(8)
if showsChevron {
make.trailing.equalTo(chevronView.snp.leading).offset(-4)
} else {
make.trailing.equalToSuperview()
}
}
}
private func updateContentConstraints(for accessory: AccessoryStyle) {
valueLabel.snp.remakeConstraints { make in
make.leading.greaterThanOrEqualTo(titleLabel.snp.trailing).offset(8)
make.centerY.equalToSuperview()
switch accessory {
case .action:
make.trailing.equalTo(accessoryLabel.snp.leading).offset(-8)
case .chevron:
make.trailing.equalTo(chevronView.snp.leading).offset(-4)
case .none:
make.trailing.equalToSuperview()
}
}
badgeContainer.snp.remakeConstraints { make in
make.leading.equalTo(titleLabel.snp.trailing).offset(8)
make.centerY.equalToSuperview()
switch accessory {
case .action:
make.trailing.lessThanOrEqualTo(accessoryLabel.snp.leading).offset(-8)
case .chevron:
make.trailing.lessThanOrEqualTo(chevronView.snp.leading).offset(-8)
case .none:
make.trailing.lessThanOrEqualToSuperview()
}
}
}
private func setupUI() {
titleLabel.font = .systemFont(ofSize: 14)
titleLabel.textColor = UIColor(hex: 0x4B5563)
titleLabel.setContentHuggingPriority(.required, for: .horizontal)
valueLabel.font = .systemFont(ofSize: 14)
valueLabel.textAlignment = .right
valueLabel.numberOfLines = 1
valueLabel.lineBreakMode = .byTruncatingTail
valueLabel.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
accessoryLabel.font = .systemFont(ofSize: 14)
accessoryLabel.textColor = AppColor.primary
accessoryLabel.setContentHuggingPriority(.required, for: .horizontal)
accessoryLabel.setContentCompressionResistancePriority(.required, for: .horizontal)
chevronView.image = UIImage(systemName: "chevron.right")
chevronView.tintColor = AppColor.text666
chevronView.contentMode = .scaleAspectFit
chevronView.setContentHuggingPriority(.required, for: .horizontal)
stackNameLabel.font = .systemFont(ofSize: 14)
stackNameLabel.textColor = AppColor.text333
stackNameLabel.textAlignment = .right
stackNameLabel.numberOfLines = 1
stackNameLabel.lineBreakMode = .byTruncatingTail
stackTypeTag.font = .systemFont(ofSize: 11, weight: .semibold)
stackTypeTag.textAlignment = .center
stackTypeTag.layer.cornerRadius = 4
stackTypeTag.clipsToBounds = true
rightStack.axis = .vertical
rightStack.alignment = .trailing
rightStack.spacing = 4
rightStack.addArrangedSubview(stackNameLabel)
rightStack.addArrangedSubview(stackTypeTag)
rightStack.isHidden = true
divider.backgroundColor = UIColor(hex: 0xE5E7EB)
addSubview(titleLabel)
addSubview(valueLabel)
addSubview(badgeContainer)
addSubview(accessoryLabel)
addSubview(chevronView)
addSubview(rightStack)
addSubview(divider)
snp.makeConstraints { make in
rowHeightConstraint = make.height.equalTo(52).constraint
}
titleLabel.snp.makeConstraints { make in
make.leading.equalToSuperview()
make.centerY.equalToSuperview()
make.width.equalTo(102)
}
chevronView.snp.makeConstraints { make in
make.trailing.equalToSuperview()
make.centerY.equalToSuperview()
make.width.height.equalTo(16)
}
accessoryLabel.snp.makeConstraints { make in
make.trailing.equalTo(chevronView.snp.leading).offset(-4)
make.centerY.equalToSuperview()
}
rightStack.snp.makeConstraints { make in
make.trailing.equalToSuperview()
make.centerY.equalToSuperview()
make.leading.greaterThanOrEqualTo(titleLabel.snp.trailing).offset(8)
}
stackTypeTag.snp.makeConstraints { make in
make.height.equalTo(22)
make.width.greaterThanOrEqualTo(56)
}
updateContentConstraints(for: .none)
divider.snp.makeConstraints { make in
make.leading.trailing.bottom.equalToSuperview()
make.height.equalTo(0.5)
}
}
}