QSLHomeController.swift 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692
  1. //
  2. // QSLHomeController.swift
  3. // QuickSearchLocation
  4. //
  5. // Created by mac on 2024/4/10.
  6. //
  7. import UIKit
  8. import SwiftyJSON
  9. import MAMapKit
  10. import AMapFoundationKit
  11. import AMapLocationKit
  12. class QSLHomeController: QSLBaseController {
  13. lazy var viewModel: QSLHomeViewModel = {
  14. return QSLHomeViewModel()
  15. }()
  16. var personalModel: QSLUserModel = QSLUserModel()
  17. // var friendList: [QSLUserModel] = [QSLUserModel]()
  18. override func viewDidLoad() {
  19. super.viewDidLoad()
  20. viewModel.initUIData()
  21. setUpMap()
  22. setUpUI()
  23. loadData()
  24. NotificationCenter.default.addObserver(self, selector: #selector(loadData), name: QSLNotification.QSLLogin, object: nil)
  25. NotificationCenter.default.addObserver(self, selector: #selector(loadData), name: QSLNotification.QSLLogout, object: nil)
  26. NotificationCenter.default.addObserver(self, selector: #selector(loadData), name: QSLNotification.QSLRefreshFriend, object: nil)
  27. NotificationCenter.default.addObserver(self, selector: #selector(loadData), name: QSLNotification.QSLRefreshRequest, object: nil)
  28. NotificationCenter.default.addObserver(self, selector: #selector(requestVip), name: QSLNotification.QSLRefreshMember, object: nil)
  29. }
  30. /// 高德地图
  31. lazy var homeMapView = {
  32. let _mapView = MAMapView()
  33. _mapView.delegate = self
  34. _mapView.minZoomLevel = 7;
  35. _mapView.maxZoomLevel = 19;
  36. _mapView.zoomLevel = 17;
  37. _mapView.showsCompass = false
  38. _mapView.showsScale = false
  39. _mapView.isRotateCameraEnabled = false
  40. _mapView.showsUserLocation = true
  41. _mapView.userTrackingMode = .follow
  42. // 关闭显示精度圈
  43. let represent = MAUserLocationRepresentation()
  44. represent.showsAccuracyRing = false
  45. _mapView.update(represent)
  46. let tap = UITapGestureRecognizer(target: self, action: #selector(mapTapAction))
  47. _mapView.addGestureRecognizer(tap)
  48. return _mapView
  49. }()
  50. /// 高德地图定位
  51. lazy var homeMapLocationM = {
  52. let _homeMapLocationM = AMapLocationManager()
  53. _homeMapLocationM.delegate = self
  54. _homeMapLocationM.distanceFilter = 100
  55. _homeMapLocationM.locatingWithReGeocode = true
  56. _homeMapLocationM.desiredAccuracy = kCLLocationAccuracyHundredMeters
  57. _homeMapLocationM.locationTimeout = 2
  58. _homeMapLocationM.reGeocodeTimeout = 2
  59. _homeMapLocationM.pausesLocationUpdatesAutomatically = false
  60. _homeMapLocationM.allowsBackgroundLocationUpdates = true
  61. return _homeMapLocationM
  62. }()
  63. /// 头部定位权限弹窗
  64. lazy var homeAuthHeaderView = {
  65. let _homeAuthHeaderView = QSLHomeAuthHeaderView()
  66. _homeAuthHeaderView.addRadius(radius: 6)
  67. return _homeAuthHeaderView
  68. }()
  69. lazy var homeButtonsView = {
  70. let _homeButtonsView = QSLHomeButtonView()
  71. return _homeButtonsView
  72. }()
  73. /// 定位按钮
  74. lazy var homeLocateBtnView = {
  75. let _homeLocateBtnView = UIView()
  76. _homeLocateBtnView.addRadius(radius: 6)
  77. _homeLocateBtnView.effectViewWithAlpha(alpha: 1, size: CGSize(width: 40, height: 40), style: .light)
  78. return _homeLocateBtnView
  79. }()
  80. lazy var homeLocateBtn = {
  81. let _homeLocateBtn = UIButton(type: .custom)
  82. _homeLocateBtn.image(UIImage(named: "home_btn_locate"))
  83. return _homeLocateBtn
  84. }()
  85. /// 无好友和未登录时的状态
  86. lazy var homeEmptyView: QSLHomeEmptyView = {
  87. let _homeEmptyView = QSLHomeEmptyView()
  88. _homeEmptyView.delegate = self
  89. _homeEmptyView.isHidden = true
  90. return _homeEmptyView
  91. }()
  92. lazy var homeFriendView: QSLHomeFriendView = {
  93. let topHeight = QSLConst.qsl_kStatusBarFrameH
  94. let view = QSLHomeFriendView(frame: CGRect(x: 0, y: QSLConst.qsl_kScreenH - viewModel.friendViewHeight - QSLConst.qsl_kTabbarFrameH, width: QSLConst.qsl_kScreenW, height: QSLConst.qsl_kScreenH - topHeight))
  95. view.scrollTopHeight = topHeight - 40
  96. view.delegate = self
  97. return view
  98. }()
  99. }
  100. // MARK: - 网络请求等
  101. extension QSLHomeController {
  102. @objc func loadData() {
  103. // viewModel.refreshDataSoure(complete: { [unowned self] in
  104. // self.homeFriendView.viewModel = self.viewModel
  105. // let friViewTopY = QSLConst.qsl_kScreenH - viewModel.friendViewHeight - QSLConst.qsl_kTabbarFrameH
  106. // homeFriendView.scrollCenterHeight = friViewTopY
  107. // homeFriendView.snp.updateConstraints { make in
  108. // make.top.equalTo(friViewTopY)
  109. // }
  110. // })
  111. self.onceLocation()
  112. if QSLBaseManager.shared.isLogin() {
  113. self.initSocket()
  114. } else {
  115. self.deposeSocket()
  116. }
  117. requestFriendList()
  118. requestVip()
  119. }
  120. // 请求好友列表
  121. @objc func requestFriendList() {
  122. self.homeMapView.removeAnnotations(self.homeMapView.annotations)
  123. viewModel.friendList.removeAll()
  124. viewModel.friendLocationList.removeAll()
  125. viewModel.friendList.append(QSLBaseManager.shared.userModel)
  126. QSLNetwork().request(.friendList(dict: [:])) { response in
  127. let list = response.mapArray(QSLUserModel.self, modelKey: "data>list")
  128. self.viewModel.friendList.append(contentsOf: list)
  129. self.homeFriendView.viewModel = self.viewModel
  130. for model in list {
  131. let pointAnnotation = MAPointAnnotation()
  132. let loc = CLLocationCoordinate2D(latitude: model.location.lat, longitude: model.location.lng)
  133. pointAnnotation.coordinate = loc
  134. if model.remark.count > 0 {
  135. pointAnnotation.title = model.remark
  136. } else {
  137. pointAnnotation.title = model.phone
  138. }
  139. pointAnnotation.subtitle = "300"
  140. let pointModel = QSLMapPointModel()
  141. pointModel.userId = model.userId
  142. pointModel.pointAnnotation = pointAnnotation
  143. self.viewModel.friendLocationList.append(pointModel)
  144. if QSLBaseManager.shared.isVip() && !model.blockedMe {
  145. self.homeMapView.addAnnotation(pointAnnotation)
  146. }
  147. }
  148. } fail: { code, error in
  149. self.homeFriendView.viewModel = self.viewModel
  150. }
  151. }
  152. // 请求vip信息
  153. @objc func requestVip() {
  154. QSLNetwork().request(.userMember(dict: [:])) { response in
  155. let memberModel = response.mapObject(QSLMemberModel.self, modelKey: "data")
  156. QSLBaseManager.shared.userModel.memberModel = memberModel
  157. if memberModel.expired {
  158. QSLBaseManager.shared.saveVipExpiredTime(time: 0)
  159. } else {
  160. QSLBaseManager.shared.saveVipExpiredTime(time: memberModel.endTimestamp)
  161. }
  162. QSLBaseManager.shared.saveUserId(id: memberModel.userId)
  163. // NotificationCenter.default.post(name: QSLNotification.QSLRefreshMember, object: nil)
  164. } fail: { code, error in
  165. }
  166. }
  167. }
  168. // MARK: - 设置地图相关方法
  169. extension QSLHomeController: MAMapViewDelegate, AMapLocationManagerDelegate {
  170. // 初始化高德地图设置
  171. func setUpMap() {
  172. AMapServices.shared().enableHTTPS = true
  173. AMapLocationManager.updatePrivacyShow(.didShow, privacyInfo: .didContain)
  174. AMapLocationManager.updatePrivacyAgree(.didAgree)
  175. homeMapLocationM.locatingWithReGeocode = true
  176. homeMapLocationM.startUpdatingLocation()
  177. }
  178. // 申请地图定位权限
  179. func mapViewRequireLocationAuth(_ locationManager: CLLocationManager!) {
  180. locationManager.requestWhenInUseAuthorization()
  181. }
  182. // 地图触摸事件
  183. @objc func mapTapAction() {
  184. if self.homeFriendView.scrollLocation != .ScrollBottom {
  185. self.homeFriendView.scrollToLocation(type: .ScrollBottom)
  186. }
  187. }
  188. // 获取一次性定位
  189. func onceLocation() {
  190. // 先停止持续定位
  191. self.homeMapLocationM.stopUpdatingLocation()
  192. self.homeMapLocationM.requestLocation(withReGeocode: true) { location, regeocode, error in
  193. if error != nil {
  194. self.personalModel = QSLBaseManager.shared.userModel
  195. // 获取电话和名字
  196. // self.personalModel.phone = QSLBaseManager.shared.userModel.phone
  197. var name = "用户\(QSLBaseManager.shared.userModel.phone.suffix(4))"
  198. if !QSLBaseManager.shared.isLogin() {
  199. name = "自己"
  200. }
  201. name = "自己"
  202. self.personalModel.remark = name
  203. // 地址
  204. self.personalModel.location.addr = "请先开启位置权限"
  205. QSLBaseManager.shared.updateUser(model: self.personalModel)
  206. if self.viewModel.friendList.isEmpty {
  207. self.viewModel.friendList.append(self.personalModel)
  208. } else {
  209. self.viewModel.friendList[0] = self.personalModel
  210. }
  211. self.homeFriendView.viewModel = self.viewModel
  212. self.homeMapLocationM.startUpdatingLocation()
  213. return
  214. }
  215. self.personalModel = QSLBaseManager.shared.userModel
  216. var name = "用户\(QSLBaseManager.shared.userModel.phone.suffix(4))"
  217. if !QSLBaseManager.shared.isLogin() {
  218. name = "自己"
  219. }
  220. name = "自己"
  221. self.personalModel.remark = name
  222. self.personalModel.location.addr = regeocode?.formattedAddress ?? "未知"
  223. self.personalModel.location.timestamp = Int(Date.secondStamp) ?? 0
  224. if let location = location {
  225. // 地图居中
  226. self.homeMapView.setCenter(location.coordinate, animated: true)
  227. self.homeFriendView.scrollLocation = .ScrollCenter
  228. self.personalModel.location.lat = location.coordinate.latitude
  229. self.personalModel.location.lng = location.coordinate.longitude
  230. // 速度
  231. self.personalModel.location.speed = location.speed >= 0 ? location.speed : 0
  232. // 朝向
  233. self.personalModel.location.bearing = location.course >= 0 ? location.course : 0
  234. }
  235. QSLBaseManager.shared.updateUser(model: self.personalModel)
  236. if QSLBaseManager.shared.isLogin() {
  237. let locationData = self.personalModel.location
  238. let addr = locationData.addr
  239. if addr != "请先开启位置权限" {
  240. self.sendSocket()
  241. }
  242. }
  243. if self.viewModel.friendList.isEmpty {
  244. self.viewModel.friendList.append(self.personalModel)
  245. } else {
  246. self.viewModel.friendList[0] = self.personalModel
  247. }
  248. print("location: \(String(describing: location))")
  249. if let regeocode = regeocode {
  250. print("reGeocode: \(regeocode)")
  251. }
  252. self.homeFriendView.viewModel = self.viewModel
  253. self.homeMapLocationM.startUpdatingLocation()
  254. }
  255. }
  256. // 持续定位
  257. func amapLocationManager(_ manager: AMapLocationManager!, didUpdate location: CLLocation!, reGeocode: AMapLocationReGeocode!) {
  258. // 获取电话和名字
  259. self.personalModel = QSLBaseManager.shared.userModel
  260. var name = "用户\(QSLBaseManager.shared.userModel.phone.suffix(4))"
  261. if !QSLBaseManager.shared.isLogin() {
  262. name = "自己"
  263. }
  264. name = "自己"
  265. self.personalModel.remark = name
  266. // 时间戳
  267. self.personalModel.location.timestamp = Int(Date.secondStamp) ?? 0
  268. // 经纬度
  269. self.personalModel.location.lat = location.coordinate.latitude
  270. self.personalModel.location.lng = location.coordinate.longitude
  271. // 速度
  272. if location.speed >= 0 {
  273. self.personalModel.location.speed = location.speed
  274. } else {
  275. self.personalModel.location.speed = 0
  276. }
  277. // 朝向
  278. if location.course >= 0 {
  279. self.personalModel.location.bearing = location.course
  280. } else {
  281. self.personalModel.location.bearing = 0
  282. }
  283. // 打印位置信息
  284. print("location: {lat: \(location.coordinate.latitude); lon: \(location.coordinate.longitude); accuracy: \(location.horizontalAccuracy)}")
  285. // 逆地理编码处理
  286. if let reGeocode = reGeocode {
  287. print("reGeocode: \(reGeocode)")
  288. self.personalModel.location.addr = reGeocode.formattedAddress
  289. } else {
  290. self.personalModel.location.addr = "请先开启位置权限"
  291. }
  292. // 保存到模块
  293. QSLBaseManager.shared.updateUser(model: self.personalModel)
  294. // 更新好友列表
  295. if self.viewModel.friendList.isEmpty {
  296. self.viewModel.friendList.append(self.personalModel)
  297. } else {
  298. self.viewModel.friendList[0] = self.personalModel
  299. }
  300. self.homeFriendView.viewModel = self.viewModel
  301. // 更新UI
  302. // self.updateHomeUI()
  303. // 如果已登录,发送定位信息
  304. if QSLBaseManager.shared.isLogin() {
  305. let locationData = self.personalModel.location
  306. let addr = locationData.addr
  307. if addr != "请先开启位置权限" {
  308. self.sendSocket()
  309. }
  310. }
  311. }
  312. func mapView(_ mapView: MAMapView!, viewFor annotation: (any MAAnnotation)!) -> MAAnnotationView! {
  313. // 处理用户位置的标注
  314. if annotation is MAUserLocation {
  315. let reuseIdentifier = "UserAnotation"
  316. var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseIdentifier) as? QSLHomeAnnotatinView
  317. if annotationView == nil {
  318. annotationView = QSLHomeAnnotatinView(annotation: annotation, reuseIdentifier: reuseIdentifier)
  319. }
  320. let name = "我"
  321. annotationView?.title = name
  322. annotationView?.isEnabled = false
  323. annotationView?.image = UIImage(named: "home_mine_anno")
  324. annotationView?.canShowCallout = false
  325. annotationView?.centerOffset = CGPoint(x: 0, y: -18)
  326. annotationView?.calloutOffset = CGPoint(x: 0, y: 0)
  327. annotationView?.zIndex = 360
  328. annotationView?.isSelected = true
  329. return annotationView
  330. }
  331. // 处理普通点标注
  332. if annotation is MAPointAnnotation {
  333. let reuseIdentifier = "OtherAnnotation"
  334. var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseIdentifier) as? QSLHomeAnnotatinView
  335. if annotationView == nil {
  336. annotationView = QSLHomeAnnotatinView(annotation: annotation, reuseIdentifier: reuseIdentifier)
  337. annotationView?.title = annotation.title
  338. }
  339. if let subtitle = annotation.subtitle as? Int {
  340. annotationView?.zIndex = subtitle
  341. }
  342. annotationView?.isEnabled = false
  343. annotationView?.image = UIImage(named: "home_mine_anno")
  344. annotationView?.canShowCallout = false
  345. annotationView?.centerOffset = CGPoint(x: 0, y: -18)
  346. annotationView?.calloutOffset = CGPoint(x: 0, y: 0)
  347. annotationView?.isSelected = true
  348. return annotationView
  349. }
  350. return nil
  351. }
  352. }
  353. // MARK: - 设置WebSocket
  354. extension QSLHomeController: QSLSocketManagerDelegate {
  355. // 初始化
  356. func initSocket() {
  357. QSLSocketManager.shared.urlString = "\(QSLApi.prodWSUrl)/websocket/\(QSLBaseManager.shared.userModel.authToken)"
  358. QSLSocketManager.shared.connect()
  359. QSLSocketManager.shared.delegate = self
  360. }
  361. // 关闭socket
  362. func deposeSocket() {
  363. QSLSocketManager.shared.urlString = ""
  364. QSLSocketManager.shared.close()
  365. QSLSocketManager.shared.delegate = nil
  366. }
  367. // 发送socket信息
  368. func sendSocket() {
  369. var message = QSLMapMessageModel()
  370. message.cmd = "u.location"
  371. var location = QSLMapTrackModel()
  372. location.lat = self.personalModel.location.lat
  373. location.lng = self.personalModel.location.lng
  374. location.addr = self.personalModel.location.addr
  375. location.speed = self.personalModel.location.speed
  376. location.bearing = self.personalModel.location.bearing
  377. location.timestamp = Int(Date.milliStamp) ?? 0
  378. message.body = location.toJSONString()
  379. QSLSocketManager.shared.sendMessage(message.toJSONString())
  380. }
  381. // 接收到消息
  382. func socketDidReceiveMessage(with string: String) {
  383. let locationModel = QSLMapMessageModel.mapModel(from: string)
  384. if let data = locationModel.body.data(using: .utf8), let list = try? JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [QSLMapTrackModel] {
  385. if locationModel.cmd == "d.location.batch" {
  386. for model in list {
  387. var isBlockedMe = false
  388. for var user in viewModel.friendList {
  389. if model.userId == user.friendId {
  390. user.location = model
  391. isBlockedMe = user.blockedMe
  392. }
  393. }
  394. if !isBlockedMe && QSLBaseManager.shared.isVip() {
  395. for location in viewModel.friendLocationList {
  396. if model.userId == location.userId {
  397. let annotation = MAPointAnnotation()
  398. let cll2d = CLLocationCoordinate2D(latitude: model.lat, longitude: model.lng)
  399. annotation.coordinate = cll2d
  400. location.pointAnnotation = annotation
  401. self.homeMapView.addAnnotation(location.pointAnnotation)
  402. }
  403. }
  404. }
  405. }
  406. self.homeFriendView.viewModel = self.viewModel
  407. }
  408. }
  409. }
  410. }
  411. // MARK: - 设置界面代理方法
  412. extension QSLHomeController: QSLHomeEmptyViewDelegate, QSLHomeFriendViewDelegate {
  413. func viewDidScroll() {
  414. switch self.homeFriendView.scrollLocation {
  415. case .ScrollTop:
  416. self.homeFriendView.snp.updateConstraints { make in
  417. make.top.equalTo(QSLConst.qsl_kStatusBarFrameH - 40.rpx)
  418. }
  419. break
  420. case .ScrollCenter:
  421. self.homeFriendView.snp.updateConstraints { make in
  422. make.top.equalTo(QSLConst.qsl_kScreenH - viewModel.friendViewHeight - QSLConst.qsl_kStatusBarFrameH)
  423. }
  424. break
  425. case .ScrollBottom:
  426. self.homeFriendView.snp.updateConstraints { make in
  427. make.top.equalTo(QSLConst.qsl_kScreenH - QSLConst.qsl_kTabbarFrameH - 56.rpx - 40.rpx)
  428. }
  429. break
  430. default:
  431. break
  432. }
  433. }
  434. func addFriendAction(isSmall: Bool) {
  435. if isSmall {
  436. QSLJumpManager.shared.pushToAdd(type: .homesmall)
  437. } else {
  438. QSLJumpManager.shared.pushToAdd(type: .homebig)
  439. }
  440. }
  441. func refreshBtnAction() {
  442. gravityInstance?.track(QSLGravityConst.home_locate)
  443. self.loadData()
  444. }
  445. // 轨迹
  446. func routeBtnAction(model: QSLUserModel) {
  447. if !QSLBaseManager.shared.isLogin() {
  448. if let view = self.tabBarController?.view {
  449. QSLAlertView.alert(view: view, title: "温馨提示", content: "登录即可体验查看轨迹记录", secondBtnClosure: {
  450. QSLJumpManager.shared.pushToLogin(type: .road)
  451. })
  452. }
  453. return
  454. }
  455. if !QSLBaseManager.shared.isVip() {
  456. QSLJumpManager.shared.pushToVip(type: .homeRoad)
  457. return
  458. }
  459. QSLJumpManager.shared.pushToRoad(type: .home, model: model)
  460. }
  461. // 点击列表的定位按钮
  462. func locateBtnAction(model: QSLUserModel) {
  463. if !QSLBaseManager.shared.isVip() {
  464. self.view.toast(text: "请先开通会员")
  465. return
  466. }
  467. if model.blockedMe {
  468. return
  469. }
  470. let location = CLLocationCoordinate2D(latitude: model.location.lat, longitude: model.location.lng)
  471. self.homeMapView.setCenter(location, animated: true)
  472. for point in self.viewModel.friendLocationList {
  473. if point.userId == model.friendId {
  474. self.homeMapView.removeAnnotation(point.pointAnnotation)
  475. point.pointAnnotation?.subtitle = "350"
  476. self.homeMapView.addAnnotation(point.pointAnnotation)
  477. }
  478. }
  479. }
  480. func emptyFriPhoneViewClick() {
  481. if let vc = self.tabBarController {
  482. QSLFriendAddAlertView.show(vc: vc) {
  483. }
  484. }
  485. }
  486. func homeFriPhoneViewClick() {
  487. if let vc = self.tabBarController {
  488. QSLFriendAddAlertView.show(vc: vc) {
  489. }
  490. }
  491. }
  492. }
  493. // MARK: - 设置UI相关方法
  494. extension QSLHomeController {
  495. // 设置基础UI
  496. func setUpUI() {
  497. view.addSubview(homeMapView)
  498. homeMapView.snp.makeConstraints { make in
  499. make.edges.equalTo(0)
  500. }
  501. // view.addSubview(homeButtonsView)
  502. // homeButtonsView.snp.makeConstraints { make in
  503. // make.size.equalTo(CGSize(width: 40, height: 104))
  504. // make.top.equalTo(QSLConst.qsl_kStatusBarFrameH + 164)
  505. // make.right.equalTo(QSLHomeViewModel.UX.viewRight)
  506. // }
  507. //
  508. // view.addSubview(homeLocateBtnView)
  509. // homeLocateBtnView.snp.makeConstraints { make in
  510. // make.size.equalTo(CGSize(width: 40, height: 40))
  511. // make.top.equalTo(self.homeButtonsView.snp.bottom).offset(16)
  512. // make.right.equalTo(QSLHomeViewModel.UX.viewRight)
  513. // }
  514. view.addSubview(homeFriendView)
  515. homeFriendView.snp.makeConstraints { make in
  516. make.left.right.equalTo(0)
  517. make.top.equalTo(QSLConst.qsl_kScreenH - viewModel.friendViewHeight - QSLConst.qsl_kTabbarFrameH)
  518. make.height.equalTo(QSLConst.qsl_kScreenH - QSLConst.qsl_kTabbarFrameH)
  519. }
  520. let friViewTopY = QSLConst.qsl_kScreenH - viewModel.friendViewHeight - QSLConst.qsl_kTabbarFrameH
  521. homeFriendView.scrollCenterHeight = friViewTopY
  522. homeFriendView.snp.updateConstraints { make in
  523. make.top.equalTo(friViewTopY)
  524. }
  525. }
  526. }