242 lines
7.9 KiB
Swift
242 lines
7.9 KiB
Swift
//
|
|
// RelationSelectPopVC.swift
|
|
// QuickLocation
|
|
//
|
|
|
|
import UIKit
|
|
import Kingfisher
|
|
|
|
final class RelationSelectPopVC: DLCustomPopVC {
|
|
|
|
var onConfirm: ((String) -> Void)?
|
|
|
|
private var selectedIdx: String
|
|
private let items: [RelationModel]
|
|
private var chipControls: [RelationChipControl] = []
|
|
|
|
init(currentIdx: String, onConfirm: ((String) -> Void)? = nil) {
|
|
self.selectedIdx = currentIdx
|
|
self.items = RelationStore.shared.list
|
|
self.onConfirm = onConfirm
|
|
super.init(nibName: nil, bundle: nil)
|
|
popStyle = .bottom
|
|
bottomCornerRadius = 40
|
|
dimmingClick = true
|
|
}
|
|
|
|
required init?(coder: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
|
|
override func viewDidLoad() {
|
|
super.viewDidLoad()
|
|
setupUI()
|
|
refreshSelection()
|
|
}
|
|
|
|
private func setupUI() {
|
|
let headerBgImage = UIImageView()
|
|
headerBgImage.image = UIImage(named: "Common/popup_header_bg")
|
|
headerBgImage.contentMode = .scaleToFill
|
|
headerBgImage.isUserInteractionEnabled = false
|
|
contentView.addSubview(headerBgImage)
|
|
headerBgImage.layoutChain
|
|
.top()
|
|
.edgesHorzontal()
|
|
.heightToWidth(120 / 375)
|
|
|
|
let titleLab = UILabel()
|
|
titleLab.text = "关系设置"
|
|
titleLab.font = .systemFont(ofSize: 18, weight: .semibold)
|
|
titleLab.textColor = UIColor(hexStr: "#293445")
|
|
contentView.addSubview(titleLab)
|
|
titleLab.layoutChain.top(22).centerX()
|
|
|
|
let closeBtn = UIButton(type: .custom)
|
|
closeBtn.setImage(UIImage(named: "MemberInfo/close_circle"), for: .normal)
|
|
closeBtn.imageEdgeInsets = UIEdgeInsets(top: 12, left: 12, bottom: 12, right: 12)
|
|
closeBtn.addTarget(self, action: #selector(close), for: .touchUpInside)
|
|
contentView.addSubview(closeBtn)
|
|
closeBtn.layoutChain.right(6).centerY(titleLab).width(44).height(44)
|
|
|
|
let columns = 5
|
|
let rows = max(1, Int(ceil(Double(max(items.count, 1)) / Double(columns))))
|
|
let chipHeight: CGFloat = 32
|
|
let rowSpacing: CGFloat = 23
|
|
let gridHeight = CGFloat(rows) * chipHeight + CGFloat(max(0, rows - 1)) * rowSpacing
|
|
|
|
let grid = UIStackView()
|
|
grid.axis = .vertical
|
|
grid.spacing = rowSpacing
|
|
grid.distribution = .fillEqually
|
|
grid.clipsToBounds = false
|
|
contentView.addSubview(grid)
|
|
grid.layoutChain
|
|
.topToBottomOfView(titleLab, offset: 22)
|
|
.left(16)
|
|
.right(16)
|
|
.height(gridHeight)
|
|
|
|
for row in 0..<rows {
|
|
let rowStack = UIStackView()
|
|
rowStack.axis = .horizontal
|
|
rowStack.spacing = 11
|
|
rowStack.distribution = .fillEqually
|
|
rowStack.alignment = .fill
|
|
rowStack.clipsToBounds = false
|
|
for col in 0..<columns {
|
|
let index = row * columns + col
|
|
if items.indices.contains(index) {
|
|
let chip = makeChip(items[index], tag: index)
|
|
chipControls.append(chip)
|
|
rowStack.addArrangedSubview(chip)
|
|
} else {
|
|
rowStack.addArrangedSubview(UIView())
|
|
}
|
|
}
|
|
grid.addArrangedSubview(rowStack)
|
|
}
|
|
|
|
let confirm = UIButton(type: .custom)
|
|
confirm.setTitle("确 定", for: .normal)
|
|
confirm.setTitleColor(.white, for: .normal)
|
|
confirm.titleLabel?.font = FontManager.boboBold(18)
|
|
confirm.setBackgroundImage(UIImage(named: "Common/button_bg_2"), for: .normal)
|
|
confirm.layer.cornerRadius = 25
|
|
confirm.clipsToBounds = true
|
|
confirm.addTarget(self, action: #selector(confirmTapped), for: .touchUpInside)
|
|
contentView.addSubview(confirm)
|
|
confirm.layoutChain
|
|
.topToBottomOfView(grid, offset: 24)
|
|
.left(50)
|
|
.right(50)
|
|
.height(50)
|
|
.bottom(3 + kSafeBottomMargin)
|
|
|
|
let height = 22 + 22 + 22 + gridHeight + 24 + 50 + 3 + kSafeBottomMargin
|
|
contentBgView.layoutChain.height(height)
|
|
contentView.layoutChain.height(height)
|
|
view.layoutIfNeeded()
|
|
}
|
|
|
|
private func makeChip(_ item: RelationModel, tag: Int) -> RelationChipControl {
|
|
let control = RelationChipControl(title: item.name, iconURL: item.icon)
|
|
control.tag = tag
|
|
control.addTarget(self, action: #selector(tapChip(_:)), for: .touchUpInside)
|
|
return control
|
|
}
|
|
|
|
private func refreshSelection() {
|
|
for (index, control) in chipControls.enumerated() {
|
|
guard items.indices.contains(index) else { continue }
|
|
let itemIdx = items[index].idx
|
|
control.isSelected = !itemIdx.isEmpty && itemIdx == selectedIdx
|
|
}
|
|
}
|
|
|
|
@objc private func tapChip(_ sender: RelationChipControl) {
|
|
guard items.indices.contains(sender.tag) else { return }
|
|
let idx = items[sender.tag].idx
|
|
guard !idx.isEmpty else {
|
|
DLToast.show(text: "关系数据异常")
|
|
return
|
|
}
|
|
selectedIdx = idx
|
|
refreshSelection()
|
|
}
|
|
|
|
@objc private func confirmTapped() {
|
|
guard !selectedIdx.isEmpty else {
|
|
DLToast.show(text: "请选择关系")
|
|
return
|
|
}
|
|
let idx = selectedIdx
|
|
dismiss(animated: true) { [weak self] in
|
|
self?.onConfirm?(idx)
|
|
}
|
|
}
|
|
|
|
@objc private func close() {
|
|
dismiss(animated: true)
|
|
}
|
|
}
|
|
|
|
private final class RelationChipControl: UIControl {
|
|
|
|
private let titleLabel = UILabel()
|
|
private let relationIconView = UIImageView()
|
|
private let iconURL: URL?
|
|
private var iconRequestVersion = 0
|
|
|
|
init(title: String, iconURL: String) {
|
|
self.iconURL = RelationStore.validIconURL(from: iconURL)
|
|
super.init(frame: .zero)
|
|
|
|
clipsToBounds = false
|
|
layer.cornerRadius = 8
|
|
layer.borderColor = UIColor(hexStr: "#E8E8E8").cgColor
|
|
|
|
titleLabel.text = title
|
|
titleLabel.font = .systemFont(ofSize: 14, weight: .medium)
|
|
titleLabel.textAlignment = .center
|
|
titleLabel.adjustsFontSizeToFitWidth = true
|
|
titleLabel.minimumScaleFactor = 0.75
|
|
addSubview(titleLabel)
|
|
titleLabel.layoutChain.edgesHorzontal(4).centerY()
|
|
|
|
relationIconView.contentMode = .scaleAspectFit
|
|
relationIconView.isUserInteractionEnabled = false
|
|
relationIconView.isHidden = true
|
|
addSubview(relationIconView)
|
|
relationIconView.layoutChain.top(-7).centerX().width(22).height(16)
|
|
|
|
applyStyle()
|
|
}
|
|
|
|
required init?(coder: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
|
|
override var isSelected: Bool {
|
|
didSet {
|
|
applyStyle()
|
|
}
|
|
}
|
|
|
|
override var isHighlighted: Bool {
|
|
didSet {
|
|
alpha = isHighlighted ? 0.7 : 1
|
|
}
|
|
}
|
|
|
|
private func applyStyle() {
|
|
backgroundColor = isSelected ? UIColor(hexStr: "#12AEF5") : .white
|
|
titleLabel.textColor = isSelected ? .white : UIColor(hexStr: "#293445")
|
|
layer.borderWidth = isSelected ? 0 : 1
|
|
updateRelationIcon()
|
|
}
|
|
|
|
private func updateRelationIcon() {
|
|
relationIconView.kf.cancelDownloadTask()
|
|
relationIconView.image = nil
|
|
relationIconView.isHidden = true
|
|
iconRequestVersion += 1
|
|
|
|
guard isSelected, let iconURL else { return }
|
|
let requestVersion = iconRequestVersion
|
|
relationIconView.kf.setImage(with: iconURL) { [weak self] result in
|
|
guard let self,
|
|
self.isSelected,
|
|
self.iconRequestVersion == requestVersion else { return }
|
|
switch result {
|
|
case .success:
|
|
self.relationIconView.isHidden = false
|
|
case .failure:
|
|
self.relationIconView.image = nil
|
|
self.relationIconView.isHidden = true
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|