jsdw_ios/QuickLocation/Section/Home/SearchLocation/SearchLocationResultView.swift

303 lines
10 KiB
Swift

//
// SearchLocationResultView.swift
// QuickLocation
//
import UIKit
class SearchLocationResultView: UIView {
let headerView = SearchLocationHeaderView()
var onSelectGroup: ((String) -> Void)?
private var chipButtons: [UIButton] = []
private var selectedGroupKey: String = ""
private var chipHeightConstraint: NSLayoutConstraint?
private var chipTopConstraint: NSLayoutConstraint?
private func setupUI() {
addSubview(navBgView)
addSubview(navView)
addSubview(scrollView)
addSubview(actionBtn)
actionBtn.layoutChain
.edgesHorzontal(20)
.height(56)
.bottom(kSafeBottomMargin + 12)
navBgView.layoutChain
.edges(excludingEdge: .bottom)
.heightToWidth(160 / 375)
navView.layoutChain
.edges(excludingEdge: .bottom)
.height(kNaviHeight)
scrollView.layoutChain
.topToBottomOfView(navView)
.edges(excludingEdge: .top)
}
func configureResult(status: String, disclaimer: String, showWarning: Bool, showGroups: Bool) {
statusPillLab.text = status
disclaimerLab.text = disclaimer
disclaimerLab.textAlignment = showWarning ? .left : .center
disclaimerIcon.isHidden = !showWarning
disclaimerRow.alignment = showWarning ? .top : .center
chipScrollView.isHidden = !showGroups
chipTopConstraint?.constant = showGroups ? 16 : 0
chipHeightConstraint?.constant = showGroups ? 32 : 0
}
func reloadGroups(_ groups: [GroupInfoModel], selectedKey: String) {
selectedGroupKey = selectedKey
chipButtons.forEach { $0.removeFromSuperview() }
chipButtons.removeAll()
chipStack.arrangedSubviews.forEach { $0.removeFromSuperview() }
for group in groups {
let btn = makeChip(title: group.name, groupKey: group.group_key)
applyChipStyle(btn, selected: group.group_key == selectedKey)
chipStack.addArrangedSubview(btn)
chipButtons.append(btn)
}
}
var currentGroupKey: String { selectedGroupKey }
func updateSubViews() {
normalResultContentView.isHidden = false
}
lazy var navBgView: UIImageView = {
let iv = UIImageView()
iv.image = UIImage(named: "Common/navBar_bg_2")
iv.contentMode = .scaleAspectFill
iv.isHidden = true
return iv
}()
lazy var navView: BaseNavigationView = {
BaseNavigationView(title: " ")
}()
lazy var scrollView: UIScrollView = {
let view = UIScrollView()
view.backgroundColor = .clear
view.showsVerticalScrollIndicator = false
view.bounces = false
let contentView = UIView()
contentView.backgroundColor = .clear
view.addSubview(contentView)
contentView.layoutChain.edges().widthToView(view)
contentView.addSubview(headerView)
headerView.layoutChain.top(12).edgesHorzontal()
contentView.addSubview(resultCard)
resultCard.layoutChain
.topToBottomOfView(headerView, offset: 34)
.edgesHorzontal(20)
contentView.addSubview(areaBadgeView)
areaBadgeView.layoutChain
.topToView(resultCard, offset: -15)
.centerX(contentView, offset: 70)
.width(74)
.height(30)
.bottom()
return view
}()
lazy var resultCard: UIView = {
let card = UIView()
card.backgroundColor = UIColor(hexStr: "#EFFAFF")
card.cornerRadius = 28
card.addSubview(normalResultContentView)
normalResultContentView.layoutChain
.top(22)
.edgesHorzontal()
.bottom()
return card
}()
private lazy var areaBadgeView: UIImageView = {
let iv = UIImageView(image: UIImage(named: "SearchLocation/area_badge"))
iv.contentMode = .scaleAspectFit
return iv
}()
private lazy var normalResultContentView: UIView = {
let contentView = UIView()
let locationRow = UIView()
contentView.addSubview(locationRow)
let pinIcon = UIImageView(image: UIImage(named: "Home/member_location"))
pinIcon.contentMode = .scaleAspectFit
locationRow.addSubview(pinIcon)
locationRow.addSubview(phoneAreaLab)
pinIcon.layoutChain.left().centerY().width(18).height(18)
phoneAreaLab.layoutChain
.leftToRightOfView(pinIcon, offset: 6)
.right()
.top()
.bottom()
locationRow.layoutChain.top().centerX()
let pillContainer = UIView()
pillContainer.backgroundColor = .white
pillContainer.cornerRadius = 16
contentView.addSubview(pillContainer)
pillContainer.addSubview(statusPillLab)
statusPillLab.layoutChain.edgesHorzontal(12).edgesVertical(14)
pillContainer.layoutChain
.topToBottomOfView(locationRow, offset: 14)
.edgesHorzontal(16)
.height(48)
contentView.addSubview(disclaimerRow)
disclaimerRow.layoutChain
.topToBottomOfView(pillContainer, offset: 12)
.edgesHorzontal(20)
contentView.addSubview(chipScrollView)
chipScrollView.translatesAutoresizingMaskIntoConstraints = false
chipTopConstraint = chipScrollView.topAnchor.constraint(equalTo: disclaimerRow.bottomAnchor, constant: 16)
chipHeightConstraint = chipScrollView.heightAnchor.constraint(equalToConstant: 32)
NSLayoutConstraint.activate([
chipTopConstraint!,
chipHeightConstraint!,
chipScrollView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16),
chipScrollView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -16),
chipScrollView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -20)
])
return contentView
}()
lazy var phoneAreaLab: UILabel = {
let label = UILabel()
label.font = .systemFont(ofSize: 18, weight: .bold)
label.textColor = UIColor(hexStr: "#293445")
return label
}()
lazy var statusPillLab: UILabel = {
let label = UILabel()
label.font = .systemFont(ofSize: 16, weight: .medium)
label.textColor = UIColor(hexStr: "#16B3FF")
label.textAlignment = .center
return label
}()
private lazy var disclaimerIcon: UIImageView = {
let iv = UIImageView(image: UIImage(named: "SearchLocation/warning"))
iv.contentMode = .scaleAspectFit
iv.layoutChain.width(12).height(12)
return iv
}()
lazy var disclaimerLab: UILabel = {
let label = UILabel()
label.font = .systemFont(ofSize: 12, weight: .regular)
label.textColor = UIColor(hexStr: "#999999")
label.numberOfLines = 0
return label
}()
private lazy var disclaimerRow: UIStackView = {
let stack = UIStackView(arrangedSubviews: [disclaimerIcon, disclaimerLab])
stack.axis = .horizontal
stack.alignment = .top
stack.spacing = 4
return stack
}()
lazy var actionBtn: UIButton = {
let btn = UIButton(type: .custom)
btn.setTitleColor(.white, for: .normal)
btn.titleLabel?.font = FontManager.boboBold(18)
btn.setBackgroundImage(UIImage(named: "Common/button_bg_2"), for: .normal)
btn.cornerRadius = 20
btn.isHidden = true
return btn
}()
var inviteBtn: UIButton { actionBtn }
private lazy var chipScrollView: UIScrollView = {
let view = UIScrollView()
view.showsHorizontalScrollIndicator = false
view.alwaysBounceHorizontal = true
view.addSubview(chipStack)
chipStack.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
chipStack.topAnchor.constraint(equalTo: view.contentLayoutGuide.topAnchor),
chipStack.leadingAnchor.constraint(equalTo: view.contentLayoutGuide.leadingAnchor),
chipStack.bottomAnchor.constraint(equalTo: view.contentLayoutGuide.bottomAnchor),
chipStack.trailingAnchor.constraint(equalTo: view.contentLayoutGuide.trailingAnchor),
chipStack.heightAnchor.constraint(equalTo: view.frameLayoutGuide.heightAnchor)
])
return view
}()
private lazy var chipStack: UIStackView = {
let stack = UIStackView()
stack.axis = .horizontal
stack.spacing = 8
stack.alignment = .fill
return stack
}()
private func makeChip(title: String, groupKey: String) -> UIButton {
let btn = UIButton(type: .custom)
btn.setTitle(title, for: .normal)
btn.titleLabel?.font = .systemFont(ofSize: 13, weight: .medium)
btn.contentEdgeInsets = UIEdgeInsets(top: 6, left: 12, bottom: 6, right: 12)
btn.layer.cornerRadius = 8
btn.layer.borderWidth = 1
btn.accessibilityIdentifier = groupKey
btn.addTarget(self, action: #selector(tapChip(_:)), for: .touchUpInside)
btn.setContentHuggingPriority(.required, for: .horizontal)
btn.setContentCompressionResistancePriority(.required, for: .horizontal)
return btn
}
private func applyChipStyle(_ btn: UIButton, selected: Bool) {
if selected {
btn.setTitleColor(UIColor(hexStr: "#16B3FF"), for: .normal)
btn.backgroundColor = .white
btn.layer.borderColor = UIColor(hexStr: "#16B3FF").cgColor
} else {
btn.setTitleColor(UIColor(hexStr: "#C0C4CC"), for: .normal)
btn.backgroundColor = UIColor(hexStr: "#F2F3F5")
btn.layer.borderColor = UIColor.clear.cgColor
}
}
@objc private func tapChip(_ sender: UIButton) {
let key = sender.accessibilityIdentifier ?? ""
selectedGroupKey = key
for btn in chipButtons {
applyChipStyle(btn, selected: btn === sender)
}
onSelectGroup?(key)
}
override init(frame: CGRect) {
super.init(frame: .zero)
backgroundColor = .white
setupUI()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}