// // 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) } } }