// // LocationPickerView.swift // QuickLocation // import UIKit #if !targetEnvironment(simulator) import AMapNaviKit #endif final class LocationPickerView: UIView { static let cellIdentifier = "LocationSuggestionCell" private var resultPanelHeightConstraint: NSLayoutConstraint? #if !targetEnvironment(simulator) lazy var mapView: MAMapView! = { let map = MAMapView() map.showsCompass = false map.showsScale = false map.zoomLevel = 15 return map }() #endif let backBtn: UIButton = { let button = UIButton(type: .custom) button.setBackgroundImage(UIImage(named: "Common/back"), for: .normal) button.backgroundColor = .clear button.extendEdgeInsets = UIEdgeInsets(top: 20, left: 18, bottom: 20, right: 20) return button }() let recenterBtn: UIButton = { let button = UIButton(type: .custom) button.setImage(UIImage(named: "IM/location_recenter"), for: .normal) button.backgroundColor = .white button.layer.cornerRadius = 10 button.layer.shadowColor = UIColor.black.cgColor button.layer.shadowOffset = CGSize(width: 0, height: 2) button.layer.shadowRadius = 6 button.layer.shadowOpacity = 0.12 return button }() let centerPinView: UIImageView = { let view = UIImageView(image: UIImage(named: "IM/location_pin")) view.contentMode = .scaleAspectFit view.isUserInteractionEnabled = false return view }() let searchField: UITextField = { let field = UITextField() field.placeholder = "搜索地点、商圈或道路" field.font = .systemFont(ofSize: 14) field.clearButtonMode = .whileEditing field.returnKeyType = .search field.backgroundColor = UIColor(hexStr: "#F3F3F3") field.cornerRadius = 11 field.leftView = UIView(frame: CGRect(x: 0, y: 0, width: 16, height: 36)) field.leftViewMode = .always return field }() let resultTableView: UITableView = { let table = UITableView(frame: .zero, style: .plain) table.backgroundColor = .white table.separatorColor = UIColor(hexStr: "#EEEEEE") table.rowHeight = 74 table.register(LocationSuggestionCell.self, forCellReuseIdentifier: cellIdentifier) table.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: kSafeBottomMargin, right: 0) return table }() let emptyLabel: UILabel = { let label = UILabel() label.font = .systemFont(ofSize: 13) label.textColor = UIColor(hexStr: "#8A8A8A") label.textAlignment = .center label.numberOfLines = 0 label.isHidden = true return label }() let confirmBtn: UIButton = { let button = UIButton(type: .custom) button.setTitle("确认", for: .normal) button.setTitleColor(.white, for: .normal) button.setTitleColor(UIColor.white.withAlphaComponent(0.6), for: .disabled) button.titleLabel?.font = .systemFont(ofSize: 14, weight: .medium) button.setBackgroundImage(UIImage(named: "Common/button_bg_2"), for: .normal) button.cornerRadius = 8 button.isEnabled = false return button }() private let resultPanel: UIView = { let view = UIView() view.backgroundColor = .white view.layer.cornerRadius = 24 view.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner] view.clipsToBounds = true return view }() override init(frame: CGRect) { super.init(frame: frame) backgroundColor = UIColor(hexStr: "#EFF7F8") setupUI() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } private func setupUI() { #if !targetEnvironment(simulator) addSubview(mapView) mapView.layoutChain.edges(excludingEdge: .bottom).bottom(250 + kSafeBottomMargin) addSubview(centerPinView) #endif addSubview(backBtn) addSubview(recenterBtn) addSubview(confirmBtn) addSubview(resultPanel) resultPanel.addSubview(searchField) resultPanel.addSubview(resultTableView) resultPanel.addSubview(emptyLabel) backBtn.layoutChain.top(kStatusBarHeight + 12).left(18).width(32).height(32) recenterBtn.layoutChain.left(13).bottomToTopOfView(resultPanel, offset: -24).width(38).height(38) confirmBtn.layoutChain.right(14).width(50).height(30).centerY(backBtn) resultPanel.layoutChain.edgesHorzontal().bottom().height(290) resultPanelHeightConstraint = resultPanel.layoutChain.constraint searchField.layoutChain.top(13).edgesHorzontal(15).height(38) resultTableView.layoutChain.topToBottomOfView(searchField, offset: 13).edgesHorzontal().bottom() emptyLabel.layoutChain.centerX().centerY().edgesHorzontal(40) #if !targetEnvironment(simulator) centerPinView.layoutChain.centerX(mapView).centerY(mapView, offset: -28).width(34).height(56) #endif } func setResultPanelHeight(_ height: CGFloat, duration: TimeInterval) { guard let resultPanelHeightConstraint, abs(resultPanelHeightConstraint.constant - height) > 0.5 else { return } layoutIfNeeded() resultPanelHeightConstraint.constant = height UIView.animate(withDuration: duration, delay: 0, options: [.beginFromCurrentState, .curveEaseInOut]) { self.layoutIfNeeded() } } #if !targetEnvironment(simulator) func cleanupMap() { mapView?.delegate = nil mapView?.removeFromSuperview() mapView = nil } #endif }