270 lines
8.4 KiB
Swift
270 lines
8.4 KiB
Swift
//
|
|
// TodayTrackDetailView.swift
|
|
// QuickLocation
|
|
//
|
|
|
|
import UIKit
|
|
import AMapNaviKit
|
|
|
|
final class TodayTrackDetailView: UIView {
|
|
|
|
let mapView: MAMapView = {
|
|
let mv = MAMapView()
|
|
mv.zoomLevel = 14
|
|
mv.showsUserLocation = false
|
|
mv.showsCompass = false
|
|
mv.showsScale = false
|
|
return mv
|
|
}()
|
|
|
|
let backBtn: UIButton = {
|
|
let btn = UIButton(type: .custom)
|
|
btn.setImage(UIImage(systemName: "chevron.left"), for: .normal)
|
|
btn.tintColor = UIColor(hexStr: "#293445")
|
|
btn.backgroundColor = .white
|
|
btn.cornerRadius = 10
|
|
return btn
|
|
}()
|
|
|
|
let titleLab: UILabel = {
|
|
let lab = UILabel()
|
|
lab.text = "今日轨迹"
|
|
lab.font = .systemFont(ofSize: 17, weight: .semibold)
|
|
lab.textColor = UIColor(hexStr: "#293445")
|
|
lab.textAlignment = .center
|
|
return lab
|
|
}()
|
|
|
|
lazy var memberCV: UICollectionView = {
|
|
let layout = UICollectionViewFlowLayout()
|
|
layout.scrollDirection = .horizontal
|
|
layout.itemSize = CGSize(width: 61, height: 90)
|
|
layout.minimumLineSpacing = 12
|
|
let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
|
|
cv.backgroundColor = .white
|
|
cv.showsHorizontalScrollIndicator = false
|
|
cv.contentInset = UIEdgeInsets(top: 0, left: 12, bottom: 0, right: 12)
|
|
cv.register(GroupMemberListCell.self)
|
|
cv.cornerRadius = 16
|
|
return cv
|
|
}()
|
|
|
|
let sheetView: UIView = {
|
|
let v = UIView()
|
|
v.backgroundColor = .white
|
|
v.layer.cornerRadius = 20
|
|
v.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
|
|
v.clipsToBounds = true
|
|
return v
|
|
}()
|
|
|
|
let handleView: UIView = {
|
|
let v = UIView()
|
|
v.backgroundColor = UIColor(hexStr: "#E5E7EB")
|
|
v.cornerRadius = 2.5
|
|
return v
|
|
}()
|
|
|
|
lazy var dateCV: UICollectionView = {
|
|
let layout = UICollectionViewFlowLayout()
|
|
layout.scrollDirection = .horizontal
|
|
layout.estimatedItemSize = CGSize(width: 56, height: 32)
|
|
layout.minimumLineSpacing = 8
|
|
let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
|
|
cv.backgroundColor = UIColor(hexStr: "#F3F4F6")
|
|
cv.showsHorizontalScrollIndicator = false
|
|
cv.contentInset = UIEdgeInsets(top: 0, left: 8, bottom: 0, right: 8)
|
|
cv.cornerRadius = 18
|
|
cv.register(TodayTrackDateCell.self)
|
|
return cv
|
|
}()
|
|
|
|
lazy var timelineTV: UITableView = {
|
|
let tv = UITableView(frame: .zero, style: .plain)
|
|
tv.separatorStyle = .none
|
|
tv.backgroundColor = .clear
|
|
tv.showsVerticalScrollIndicator = false
|
|
tv.register(TodayTrackStayCell.self)
|
|
tv.rowHeight = UITableView.automaticDimension
|
|
tv.estimatedRowHeight = 72
|
|
return tv
|
|
}()
|
|
|
|
let emptyLab: UILabel = {
|
|
let lab = UILabel()
|
|
lab.text = "暂无轨迹"
|
|
lab.font = .systemFont(ofSize: 14, weight: .medium)
|
|
lab.textColor = UIColor(hexStr: "#9CA3AF")
|
|
lab.textAlignment = .center
|
|
lab.isHidden = true
|
|
return lab
|
|
}()
|
|
|
|
private(set) var sheetHeightConstraint: NSLayoutConstraint?
|
|
|
|
override init(frame: CGRect) {
|
|
super.init(frame: frame)
|
|
backgroundColor = UIColor(hexStr: "#F5F7FA")
|
|
setupUI()
|
|
}
|
|
|
|
required init?(coder: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
|
|
private func setupUI() {
|
|
addSubview(mapView)
|
|
mapView.layoutChain.edges()
|
|
|
|
addSubview(backBtn)
|
|
backBtn.layoutChain
|
|
.top(kStatusBarHeight + 6)
|
|
.left(15)
|
|
.width(36)
|
|
.height(36)
|
|
|
|
addSubview(titleLab)
|
|
titleLab.layoutChain
|
|
.centerY(backBtn)
|
|
.centerX()
|
|
|
|
addSubview(memberCV)
|
|
memberCV.layoutChain
|
|
.topToBottomOfView(backBtn, offset: 12)
|
|
.edgesHorzontal(15)
|
|
.height(100)
|
|
|
|
addSubview(sheetView)
|
|
let sheetH = sheetView.heightAnchor.constraint(equalToConstant: 320 + kSafeBottomMargin)
|
|
sheetH.isActive = true
|
|
sheetHeightConstraint = sheetH
|
|
sheetView.translatesAutoresizingMaskIntoConstraints = false
|
|
NSLayoutConstraint.activate([
|
|
sheetView.leadingAnchor.constraint(equalTo: leadingAnchor),
|
|
sheetView.trailingAnchor.constraint(equalTo: trailingAnchor),
|
|
sheetView.bottomAnchor.constraint(equalTo: bottomAnchor)
|
|
])
|
|
|
|
sheetView.addSubview(handleView)
|
|
handleView.layoutChain
|
|
.top(8)
|
|
.centerX()
|
|
.width(36)
|
|
.height(5)
|
|
|
|
sheetView.addSubview(dateCV)
|
|
dateCV.layoutChain
|
|
.topToBottomOfView(handleView, offset: 12)
|
|
.edgesHorzontal(15)
|
|
.height(36)
|
|
|
|
sheetView.addSubview(timelineTV)
|
|
timelineTV.layoutChain
|
|
.topToBottomOfView(dateCV, offset: 12)
|
|
.edgesHorzontal(15)
|
|
.bottom(kSafeBottomMargin + 8)
|
|
|
|
sheetView.addSubview(emptyLab)
|
|
emptyLab.layoutChain
|
|
.centerX()
|
|
.topToBottomOfView(dateCV, offset: 40)
|
|
}
|
|
|
|
func cleanupMap() {
|
|
mapView.removeAnnotations(mapView.annotations)
|
|
mapView.removeOverlays(mapView.overlays)
|
|
mapView.delegate = nil
|
|
}
|
|
}
|
|
|
|
// MARK: - Date cell
|
|
|
|
final class TodayTrackDateCell: UICollectionViewCell {
|
|
private let titleLab = UILabel()
|
|
|
|
override init(frame: CGRect) {
|
|
super.init(frame: frame)
|
|
contentView.backgroundColor = .clear
|
|
contentView.cornerRadius = 14
|
|
titleLab.font = .systemFont(ofSize: 13, weight: .semibold)
|
|
titleLab.textAlignment = .center
|
|
contentView.addSubview(titleLab)
|
|
titleLab.layoutChain.edges(UIEdgeInsets(top: 6, left: 12, bottom: 6, right: 12))
|
|
}
|
|
|
|
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
|
|
|
|
func configure(title: String, selected: Bool) {
|
|
titleLab.text = title
|
|
titleLab.textColor = selected ? UIColor(hexStr: "#293445") : UIColor(hexStr: "#9CA3AF")
|
|
contentView.backgroundColor = selected ? .white : .clear
|
|
}
|
|
}
|
|
|
|
// MARK: - Stay cell
|
|
|
|
final class TodayTrackStayCell: UITableViewCell {
|
|
private let dot = UIView()
|
|
private let line = UIView()
|
|
private let titleLab = UILabel()
|
|
private let tagStack = UIStackView()
|
|
|
|
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
|
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
|
selectionStyle = .none
|
|
backgroundColor = .clear
|
|
contentView.backgroundColor = .clear
|
|
|
|
dot.backgroundColor = UIColor(hexStr: "#16B3FF")
|
|
dot.cornerRadius = 5
|
|
contentView.addSubview(dot)
|
|
dot.layoutChain.top(8).left().width(10).height(10)
|
|
|
|
line.backgroundColor = UIColor(hexStr: "#E5E7EB")
|
|
contentView.addSubview(line)
|
|
line.layoutChain
|
|
.topToBottomOfView(dot, offset: 2)
|
|
.centerX(dot)
|
|
.width(2)
|
|
.bottom()
|
|
|
|
titleLab.font = .systemFont(ofSize: 14, weight: .medium)
|
|
titleLab.textColor = UIColor(hexStr: "#293445")
|
|
titleLab.numberOfLines = 2
|
|
contentView.addSubview(titleLab)
|
|
titleLab.layoutChain
|
|
.top(4)
|
|
.leftToRightOfView(dot, offset: 12)
|
|
.right()
|
|
|
|
tagStack.axis = .horizontal
|
|
tagStack.spacing = 8
|
|
contentView.addSubview(tagStack)
|
|
tagStack.layoutChain
|
|
.topToBottomOfView(titleLab, offset: 8)
|
|
.leftToView(titleLab)
|
|
.bottom(12)
|
|
}
|
|
|
|
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
|
|
|
|
func configure(title: String, tags: [String], isFirst: Bool, isLast: Bool) {
|
|
titleLab.text = title
|
|
line.isHidden = isLast
|
|
dot.backgroundColor = isFirst ? UIColor(hexStr: "#16B3FF") : UIColor(hexStr: "#9CA3AF")
|
|
tagStack.arrangedSubviews.forEach { $0.removeFromSuperview() }
|
|
for tag in tags {
|
|
let lab = UILabel()
|
|
lab.text = tag
|
|
lab.font = .systemFont(ofSize: 12, weight: .medium)
|
|
lab.textColor = UIColor(hexStr: "#6B7280")
|
|
let wrap = UIView()
|
|
wrap.backgroundColor = UIColor(hexStr: "#F3F4F6")
|
|
wrap.cornerRadius = 8
|
|
wrap.addSubview(lab)
|
|
lab.layoutChain.edges(UIEdgeInsets(top: 4, left: 8, bottom: 4, right: 8))
|
|
tagStack.addArrangedSubview(wrap)
|
|
}
|
|
}
|
|
}
|