// // CreateSchedulePopView.swift // QuickLocation // // Created by 八条 on 2026/6/23. // import UIKit import RxSwift import RxCocoa import RxDataSources import BRPickerView import RxGesture import CoreLocation import TagListView // MARK: - CreateSchedulePopView class CreateSchedulePopView: UIView { var disposeBag = DisposeBag() func setupTagData(_ list: [GroupInfoModel]) { let nameArr = list.map { $0.name } tagListView.removeAllTags() tagListView.addTags(nameArr) tagListView.tagViews.forEach { $0.layer.cornerRadius = 4 } tagListView.invalidateIntrinsicContentSize() // 通知系统重新算高 } // MARK: - UI private func setupUI() { addSubview(lineView) addSubview(dateView) addSubview(detailView) addSubview(scrollView) lineView.layoutChain .top(15) .centerX() .width(36) .height(4) dateView.layoutChain .topToBottomOfView(lineView, offset: 19) .edgesHorzontal() .height(22) detailView.layoutChain .topToBottomOfView(dateView, offset: 20) .edgesHorzontal() .height(22) scrollView.layoutChain .topToBottomOfView(detailView, offset: 15) .edges(excludingEdge: .top) } // MARK: - Views lazy var lineView: UIView = { let v = UIView() v.backgroundColor = UIColor(hexStr: "#EBEBEB") v.cornerRadius = 2 return v }() lazy var dateView: UIView = { let view = UIView() view.backgroundColor = .clear let titleLab = UILabel() titleLab.text = "行程日期:" titleLab.font = .systemFont(ofSize: 14, weight: .medium) titleLab.textColor = ThemeManager.shared.color.titleAuxColor view.addSubview(titleLab) titleLab.layoutChain.left(15).centerY() view.addSubview(dateLab) dateLab.layoutChain.leftToRightOfView(titleLab).centerY() return view }() lazy var dateLab: UILabel = { let label = UILabel() label.font = .systemFont(ofSize: 14, weight: .medium) label.textColor = UIColor(hexStr: "#16B3FF") label.isUserInteractionEnabled = true let fmt = DateFormatter() fmt.dateFormat = "yyyy年MM月dd日" label.text = fmt.string(from: Date()) return label }() lazy var detailView: UIView = { let view = UIView() view.backgroundColor = .clear let titleLab = UILabel() titleLab.text = "行程详情" titleLab.font = .systemFont(ofSize: 14, weight: .medium) titleLab.textColor = ThemeManager.shared.color.titleAuxColor view.addSubview(titleLab) titleLab.layoutChain.left(15).centerY() view.addSubview(addBtn) addBtn.layoutChain.right(15).centerY().width(18).height(18) return view }() lazy var addBtn: UIButton = { let btn = UIButton(type: .custom) btn.setImage(UIImage(named: "Schedule/add"), for: .normal) btn.backgroundColor = .clear btn.extendEdgeInsets = UIEdgeInsets(top: 30, left: 30, bottom: 10, right: 15) return btn }() lazy var scrollView: UIScrollView = { let view = UIScrollView() view.backgroundColor = .white view.showsHorizontalScrollIndicator = false view.bounces = false view.delaysContentTouches = false let contentView = UIView() contentView.backgroundColor = .clear view.addSubview(contentView) contentView.layoutChain .edges().widthToView(view) contentView.addSubview(tableView) tableView.layoutChain .top() .edgesHorzontal() contentView.addSubview(shareGroupView) shareGroupView.layoutChain .topToBottomOfView(tableView, offset: 5) .edgesHorzontal() contentView.addSubview(createBtn) createBtn.layoutChain .topToBottomOfView(shareGroupView, offset: 30) .edgesHorzontal(30) .height(50) .bottom(kSafeBottomMargin + 10) return view }() lazy var tableView: UITableView = { let tv = UITableView(frame: .zero, style: .plain) tv.backgroundColor = .clear tv.separatorStyle = .none tv.estimatedRowHeight = 122 tv.isScrollEnabled = false tv.showsVerticalScrollIndicator = false tv.bounces = false tv.register(SchedulePointCell.self) return tv }() /// 选择分享的圈子 lazy var shareGroupView: UIView = { let view = UIView() view.backgroundColor = .clear let titleLab = UILabel() titleLab.text = "选择分享的圈子" titleLab.font = .systemFont(ofSize: 14, weight: .medium) titleLab.textColor = ThemeManager.shared.color.titleAuxColor view.addSubview(titleLab) titleLab.layoutChain.left(15).top() view.addSubview(tagListView) tagListView.layoutChain .topToBottomOfView(titleLab, offset: 15) .edgesHorzontal(15) .bottom(15) return view }() lazy var tagListView: TagListView = { let view = TagListView() view.textFont = UIFont.systemFont(ofSize: 12, weight: .medium) view.textColor = UIColor(hexStr: "#999999") view.tagBackgroundColor = UIColor(hexStr: "#F2F2F2") view.selectedTextColor = UIColor(hexStr: "#16B3FF") view.tagSelectedBackgroundColor = UIColor(hexStr: "#E3F6FF") view.selectedBorderColor = UIColor(hexStr: "#16B3FF") view.paddingX = 15 // 水平内边距 view.paddingY = 10 // 垂直内边距 view.alignment = .left // 对齐 view.translatesAutoresizingMaskIntoConstraints = false return view }() lazy var createBtn: UIButton = { let btn = UIButton(type: .custom) btn.setTitle("立即创建", for: .normal) btn.setTitleColor(.white, for: .normal) btn.titleLabel?.font = .systemFont(ofSize: 16, weight: .medium) btn.setBackgroundImage(UIImage(named: "Common/button_bg_2"), for: .normal) btn.cornerRadius = 25 return btn }() override init(frame: CGRect) { super.init(frame: frame) backgroundColor = .white setupUI() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func layoutSubviews() { super.layoutSubviews() layoutIfNeeded() setCornerRadius(corners: [.topLeft, .topRight], withCornerRadii: CGSize(width: 30, height: 30)) } } // MARK: - SchedulePointCell class SchedulePointCell: UITableViewCell { var disposeBag = DisposeBag() var onLocationTap: (() -> Void)? var onTimeTap: (() -> Void)? func configure(item: SchedulePointItem, index: Int, total: Int, onDelete: @escaping () -> Void) { disposeBag = DisposeBag() indexLabel.text = "\(index + 1)" locationLabel.text = item.locationName.isEmpty ? "点击选择地点" : item.locationName locationLabel.rx.tapGesture .when(.recognized) .subscribe(onNext: { [weak self] _ in self?.onLocationTap?() }) .disposed(by: disposeBag) if let expectedTime = item.expectedTime { timeLabel.text = formatTime(expectedTime) } else { timeLabel.text = "请选择到达时间" } timeLabel.rx.tapGesture .when(.recognized) .subscribe(onNext: { [weak self] _ in self?.onTimeTap?() }) .disposed(by: disposeBag) // 左侧竖线:仅有一条时不显示虚线,首条顶部不画、末条底部不画 topDashView.isHidden = total <= 1 || index == 0 bottomDashView.isHidden = total <= 1 || index == total - 1 // 删除 deleteBtn.rx.tap .subscribe(onNext: { onDelete() }) .disposed(by: disposeBag) } private func formatTime(_ date: Date) -> String { let fmt = DateFormatter() fmt.dateFormat = "HH:mm" return fmt.string(from: date) } // MARK: - Init override init(style: CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) selectionStyle = .none backgroundColor = .clear setupViews() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } private func setupViews() { contentView.addSubview(topDashView) contentView.addSubview(pointIcon) contentView.addSubview(bottomDashView) contentView.addSubview(cardView) cardView.addSubview(cardCornerView) cardCornerView.addSubview(indexLabel) cardCornerView.addSubview(locationLabel) cardCornerView.addSubview(timeLabel) cardCornerView.addSubview(remarkTF) cardCornerView.addSubview(deleteBtn) topDashView.layoutChain .top().width(2) pointIcon.layoutChain .centerY() .left(22) .width(18).height(18) topDashView.layoutChain .centerX(pointIcon) .bottomToTopOfView(pointIcon, offset: -10) bottomDashView.layoutChain .topToBottomOfView(pointIcon, offset: 10) .centerX(pointIcon) .width(2) .bottom() // 右侧卡片 cardView.layoutChain .top(15) .leftToRightOfView(pointIcon, offset: 20) .right(15) // .height(92) .bottom(15) cardCornerView.layoutChain.edges() indexLabel.layoutChain .top().left() .width(30).height(20) locationLabel.layoutChain .topToBottomOfView(indexLabel, offset: 10) .left(10) .compressionHorizontal(.defaultLow) timeLabel.layoutChain .topToView(locationLabel) .right(10) .compressionHorizontal(.required) locationLabel.layoutChain.rightToLeftOfView(timeLabel, offset: -8) deleteBtn.layoutChain .right(15) .width(14).height(14) remarkTF.layoutChain .topToBottomOfView(locationLabel, offset: 15) .leftToView(locationLabel) .rightToLeftOfView(deleteBtn, offset: -10) .bottom(15) deleteBtn.layoutChain.centerY(remarkTF) } // MARK: - Views private let topDashView: UIView = { let v = UIView() v.backgroundColor = UIColor(hexStr: "#E0E0E0") v.isHidden = true return v }() private let pointIcon: UIImageView = { let iv = UIImageView(image: UIImage(named: "Schedule/point")) iv.contentMode = .scaleAspectFit return iv }() private let bottomDashView: UIView = { let v = UIView() v.backgroundColor = UIColor(hexStr: "#E0E0E0") v.isHidden = true return v }() private let cardView: UIView = { let view = UIView() view.backgroundColor = .clear view.layer.shadowColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.05).cgColor view.layer.shadowOffset = CGSize(width: 0, height: 0) view.layer.shadowOpacity = 1 view.layer.shadowRadius = 8 return view }() lazy var cardCornerView: UIView = { let view = UIView() view.backgroundColor = .white view.cornerRadius = 10 return view }() private let indexLabel: UILabel = { let l = UILabel() l.backgroundColor = UIColor(hexStr: "#DCF4FF") l.textColor = UIColor(hexStr: "#176F9B") l.font = .systemFont(ofSize: 12, weight: .medium) l.textAlignment = .center return l }() private let locationLabel: UILabel = { let l = UILabel() l.font = .systemFont(ofSize: 14, weight: .medium) l.textColor = UIColor(hexStr: "#333333") // l.numberOfLines = 0 return l }() private let timeLabel: UILabel = { let l = UILabel() l.font = .systemFont(ofSize: 12, weight: .medium) l.textColor = UIColor(hexStr: "#333333") l.isUserInteractionEnabled = true l.textAlignment = .right return l }() lazy var remarkTF: UITextField = { let tf = UITextField() tf.font = .systemFont(ofSize: 12) tf.placeholder = "在此添加备注..." tf.returnKeyType = .done return tf }() private let deleteBtn: UIButton = { let btn = UIButton(type: .custom) btn.setImage(UIImage(named: "Schedule/delete"), for: .normal) btn.extendEdgeInsets = UIEdgeInsets(top: 10, left: 15, bottom: 15, right: 15) return btn }() override func layoutSubviews() { super.layoutSubviews() cardCornerView.layoutIfNeeded() indexLabel.setCornerRadius(corners: [.bottomRight], withCornerRadii: CGSize(width: 10, height: 10)) } }