QSLSearchFriendVC.swift 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. //
  2. // QSLSearchFriendVC.swift
  3. // QuickSearchLocation
  4. //
  5. // Created by Destiny on 2025/10/23.
  6. //
  7. import UIKit
  8. import MAMapKit
  9. import Kingfisher
  10. import AMapSearchKit
  11. class QSLSearchFriendVC: QSLBaseController {
  12. var searchPhone = ""
  13. var isMove = false
  14. var isLoading = false
  15. override func viewDidLoad() {
  16. super.viewDidLoad()
  17. self.setUI()
  18. }
  19. func setUI(){
  20. setUpMap()
  21. if(QSLConfig.phoneLocationEnable && searchPhone.count > 0){
  22. startLoading()
  23. QSLNetwork().request(.userPhoneAttribution(dict: ["phoneNumber":searchPhone])) { response in
  24. let model = response.mapObject(QSLConfModel.self, modelKey: "data")
  25. if(model.location.count > 0){
  26. var currentSearchKey = model.location
  27. if(model.location.contains("市") && model.location.contains("省")){
  28. let pattern = "省(.+?市)"
  29. if let regex = try? NSRegularExpression(pattern: pattern),
  30. let match = regex.firstMatch(in: currentSearchKey, range: NSRange(currentSearchKey.startIndex..., in: currentSearchKey)),
  31. let range = Range(match.range(at: 1), in: currentSearchKey) {
  32. currentSearchKey = String(currentSearchKey[range])
  33. }
  34. }
  35. self.requestAmapLocation(currentSearchKey)
  36. return
  37. }
  38. self.startLocalMapAnimation()
  39. } fail: { code, msg in
  40. self.startLocalMapAnimation()
  41. }
  42. } else{
  43. startLocalMapAnimation()
  44. }
  45. }
  46. func requestAmapLocation(_ str : String){
  47. let req = AMapDistrictSearchRequest.init()
  48. req.keywords = str
  49. req.requireExtension = true
  50. self.mapSearch.aMapDistrictSearch(req)
  51. }
  52. func startLocalMapAnimation(){
  53. let randomCityCoordinate: (city: String, province: String, latitude: Double, longitude: Double) = [
  54. ("北京市", "北京市", 39.90403, 116.40753),
  55. ("上海市", "上海市", 31.23037, 121.47370),
  56. ("广州市", "广东省", 23.12908, 113.26436),
  57. ("武汉市", "湖北省", 30.59276, 114.30525),
  58. ("成都市", "四川省", 30.65984, 104.06304),
  59. ("西安市", "陕西省", 34.34127, 108.93984),
  60. ("沈阳市", "辽宁省", 41.80570, 123.43147),
  61. ("南京市", "江苏省", 32.05838, 118.79647),
  62. ("郑州市", "河南省", 34.74661, 113.62533),
  63. ("乌鲁木齐市", "新疆维吾尔自治区", 43.82559, 87.61688)
  64. ].randomElement()!
  65. startMapAnimation(longitude: randomCityCoordinate.longitude, latitude: randomCityCoordinate.latitude)
  66. startLoading()
  67. }
  68. func startLoading(){
  69. if(!isLoading){
  70. let bgView = UIView.init(frame: CGRect.init(x: 0, y: 0, width: QSLConst.qsl_kScreenW, height: QSLConst.qsl_kScreenH))
  71. self.view.addSubview(bgView)
  72. bgView.backgroundColor = UIColor.init(white: 0, alpha: 0.45)
  73. self.loadingView = QSLLoadingView(frame: CGRect(x: 0, y: 0, width: 170.rpx, height: 170.rpx))
  74. self.loadingView.center = view.center
  75. self.view.addSubview(self.loadingView)
  76. self.loadingView.completion = {
  77. print("加载完成")
  78. }
  79. self.loadingView.progress = 0 // 设置进度
  80. // 模拟进度更新
  81. Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { timer in
  82. self.loadingView.progress += 1
  83. if self.loadingView.progress >= 100 {
  84. timer.invalidate()
  85. }
  86. }
  87. isLoading = true
  88. }
  89. }
  90. func startMapAnimation(longitude:Double, latitude:Double){
  91. isMove = true
  92. roadMapView.setZoomLevel(4, animated: true)
  93. roadMapView.setCenter(CLLocationCoordinate2D(latitude: latitude, longitude: longitude), animated: true)
  94. DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
  95. self.roadMapView.setZoomLevel(6, animated: true)
  96. let randomProgress1 = CGFloat.random(in: 20...35)
  97. if self.loadingView.progress < randomProgress1 {
  98. self.loadingView.progress = randomProgress1
  99. }
  100. }
  101. DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
  102. self.roadMapView.setZoomLevel(7, animated: true)
  103. let randomProgress2 = CGFloat.random(in: 45...70)
  104. if self.loadingView.progress < randomProgress2 {
  105. self.loadingView.progress = randomProgress2
  106. }
  107. }
  108. DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
  109. self.roadMapView.setZoomLevel(8, animated: true)
  110. let randomProgress3 = CGFloat.random(in: 86...100)
  111. if self.loadingView.progress < randomProgress3 {
  112. self.loadingView.progress = randomProgress3
  113. }
  114. }
  115. DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
  116. self.navigationController?.popViewController(animated: false)
  117. QSLJumpManager.shared.pushToVip(type: QSLVipJumpType.add)
  118. }
  119. }
  120. // 初始化高德地图设置
  121. func setUpMap() {
  122. AMapServices.shared().enableHTTPS = true
  123. self.initView()
  124. }
  125. // 高德地图
  126. lazy var roadMapView = {
  127. let _mapView = MAMapView()
  128. _mapView.delegate = self
  129. _mapView.showsUserLocation = false
  130. _mapView.isUserInteractionEnabled = false
  131. _mapView.zoomLevel = 3;
  132. _mapView.isShowsBuildings = false
  133. _mapView.showsCompass = false
  134. _mapView.showsScale = false
  135. _mapView.isRotateCameraEnabled = false
  136. _mapView.mapType = .satellite
  137. //高德地图用的坐标帮我生成10个 分别是中国10个不同省份的省的市中心坐标
  138. return _mapView
  139. }()
  140. lazy var mapSearch: AMapSearchAPI = {
  141. let item = AMapSearchAPI.init()
  142. item?.delegate = self
  143. return item!
  144. }()
  145. lazy var loadingView: QSLLoadingView = {
  146. let item = QSLLoadingView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
  147. return item
  148. }()
  149. }
  150. // MARK: - 设置地图相关方法
  151. extension QSLSearchFriendVC:MAMapViewDelegate {
  152. func mapView(_ mapView: MAMapView!, viewFor annotation: (any MAAnnotation)!) -> MAAnnotationView! {
  153. if annotation is MAPointAnnotation {
  154. let reuseIdentifier = "pointReuseIdentifier"
  155. // 尝试从缓存池中重用AnnotationView
  156. var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseIdentifier) as? QSLHomeAnnotatinView
  157. if annotationView == nil {
  158. annotationView = QSLHomeAnnotatinView(annotation: annotation, reuseIdentifier: reuseIdentifier)
  159. annotationView?.title = annotation.title
  160. }
  161. // 设置AnnotationView属性
  162. annotationView?.isEnabled = false
  163. annotationView?.image = UIImage(named: annotation.subtitle ?? "")
  164. annotationView?.canShowCallout = false
  165. // 设置偏移量
  166. annotationView?.centerOffset = CGPoint(x: 0, y: -18)
  167. annotationView?.calloutOffset = CGPoint(x: 0, y: -5)
  168. // 判断标题是否是“终点”,决定是否选中
  169. annotationView?.isSelected = true
  170. return annotationView
  171. }
  172. return nil
  173. }
  174. func mapView(_ mapView: MAMapView!, didSingleTappedAt coordinate: CLLocationCoordinate2D) {
  175. }
  176. }
  177. extension QSLSearchFriendVC : AMapSearchDelegate{
  178. func onDistrictSearchDone(_ request: AMapDistrictSearchRequest!, response: AMapDistrictSearchResponse!) {
  179. if(!isMove){
  180. if(response.districts.count > 0){
  181. let dist : AMapDistrict = response.districts[0]
  182. startMapAnimation(longitude: dist.center.longitude, latitude: dist.center.latitude)
  183. }else{
  184. startLocalMapAnimation()
  185. }
  186. }
  187. }
  188. func aMapSearchRequest(_ request: Any!, didFailWithError error: (any Error)!) {
  189. if(!isMove){
  190. startLocalMapAnimation()
  191. }
  192. }
  193. }
  194. extension QSLSearchFriendVC {
  195. func initView() {
  196. self.view.addSubview(roadMapView)
  197. roadMapView.snp.makeConstraints { make in
  198. make.top.right.left.equalTo(0)
  199. make.edges.equalToSuperview()
  200. }
  201. }
  202. }