303 lines
10 KiB
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")
|
|
}
|
|
}
|