QSLHomeFriendView.swift 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638
  1. //
  2. // QSLHomeFriendView.swift
  3. // QuickSearchLocation
  4. //
  5. // Created by mac on 2024/4/12.
  6. //
  7. import UIKit
  8. import YYText
  9. import SnapKit
  10. enum FriendViewLocation {
  11. case ScrollTop
  12. case ScrollCenter
  13. case ScrollBottom
  14. }
  15. protocol QSLHomeFriendViewDelegate: NSObjectProtocol {
  16. func refreshBtnAction()
  17. func homeFriPhoneViewClick()
  18. func routeBtnAction(model: QSLUserModel)
  19. func locateBtnAction(model: QSLUserModel)
  20. func addFriendAction(isSmall: Bool)
  21. func viewDidScroll()
  22. }
  23. class QSLHomeFriendView: UIView {
  24. weak var delegate: QSLHomeFriendViewDelegate?
  25. // 动态约束处理
  26. var couponViewTopConstraint: Constraint? = nil
  27. private var friBgViewTopConstraint: Constraint? // 新增:保存friBgView的顶部约束
  28. var viewModel:QSLHomeViewModel? {
  29. didSet {
  30. friTableView.reloadData()
  31. }
  32. }
  33. /// 位置
  34. var scrollLocation: FriendViewLocation?
  35. /// 滑动到最后停下来的位置
  36. var scrollStopY: CGFloat?
  37. /// 滑动顶部距离顶部的距离
  38. var scrollTopHeight: CGFloat?
  39. /// 滑动中间距离顶部的距离
  40. var scrollCenterHeight: CGFloat?
  41. /// 滑动底部距离顶部的距离
  42. var scrollBottomHeight: CGFloat?
  43. lazy var friMapLogoImageView: UIImageView = {
  44. let imageView = UIImageView()
  45. imageView.isHidden = true
  46. imageView.image = UIImage(named: "home_friends_map_logo")
  47. return imageView
  48. }()
  49. lazy var friExpandButton: UIButton = {
  50. let button = UIButton(type: .custom)
  51. button.backgroundColor = UIColor.hexStringColor(hexString: "#333333", alpha: 0.6)
  52. button.addRadius(radius: 2)
  53. return button
  54. }()
  55. lazy var refreshButton: UIButton = {
  56. let button = UIButton(type: .custom)
  57. button.setBackgroundImage(UIImage(named: "home_refresh_btn"), for: .normal)
  58. button.addTarget(self, action: #selector(refreshBtnAction), for: .touchUpInside)
  59. return button
  60. }()
  61. lazy var couponView: UIImageView = {
  62. let view = UIImageView()
  63. view.image = UIImage(named: "home_activity_bg")
  64. view.isUserInteractionEnabled = true
  65. view.isHidden = true
  66. let tapG = UITapGestureRecognizer.init(target: self, action: #selector(unlockBtnAction))
  67. view.addGestureRecognizer(tapG)
  68. return view
  69. }()
  70. lazy var couponLabel: YYLabel = {
  71. let label = YYLabel()
  72. return label
  73. }()
  74. lazy var countdownLabel: QSLCountdownView = {
  75. let label = QSLCountdownView(frame: CGRectMake(0, 0, QSLConst.qsl_kScreenW - 24.rpx, 17.rpx),type: 1)
  76. return label
  77. }()
  78. lazy var couponBtn: UILabel = {
  79. let label = UILabel()
  80. label.gradientBackgroundColor(color1: UIColor.hexStringColor(hexString: "#FFFEF3", alpha: 1), color2: UIColor.hexStringColor(hexString: "#FFE6C0", alpha: 1), width: 65.rpx, height: 28.rpx, direction: .horizontal)
  81. label.text("去使用")
  82. label.textAlignment = .center
  83. label.font = UIFont.textM(14)
  84. label.textColor = (UIColor.hexStringColor(hexString: "#3A331C"))
  85. label.addRadius(radius: 14.rpx)
  86. return label
  87. }()
  88. lazy var friBgView: UIView = {
  89. let view = UIView()
  90. view.clipsToBounds = true
  91. view.backgroundColor = QSLColor.backGroundColor
  92. view.addRadius(radius: 12.rpx)
  93. return view
  94. }()
  95. lazy var friHeaderView: UIView = {
  96. let view = UIView(frame: CGRect(x: 0, y: 0, width: QSLConst.qsl_kScreenW, height: 61.rpx))
  97. if let image = UIImage.gradient([UIColor.hexStringColor(hexString: "#FFFFFF", alpha: 1), UIColor.hexStringColor(hexString: "#FFFFFF", alpha: 0)], size: CGSize(width: qsl_kScreenW, height: 61.rpx), locations: [0, 1], direction: .vertical) {
  98. view.backgroundColor = UIColor(patternImage: image)
  99. }
  100. view.addFourCorner(topLeft: 12.rpx, topRight: 12.rpx, bottomLeft: 0, bottomRight: 0)
  101. return view
  102. }()
  103. lazy var friHeaderTitleIcon: UIImageView = {
  104. let imageView = UIImageView()
  105. imageView.image = UIImage(named: "home_friends_header_title")
  106. return imageView
  107. }()
  108. lazy var friHeaderAddBtn: UIButton = {
  109. let btn = UIButton()
  110. btn.setBackgroundImage(UIImage(named: "home_friends_header_add_btn_bg"), for: .normal)
  111. btn.image(UIImage(named: "home_friends_header_add_icon"))
  112. btn.title("查找好友")
  113. btn.mediumFont(15)
  114. btn.textColor(.white)
  115. btn.setImageTitleLayout(.imgLeft, spacing: 0)
  116. btn.addTarget(self, action: #selector(topAddButtonAction), for: .touchUpInside)
  117. return btn
  118. }()
  119. lazy var friTableView: UITableView = {
  120. let tableView = UITableView(frame: .zero, style: .grouped)
  121. tableView.backgroundColor = .clear
  122. tableView.separatorStyle = .none
  123. tableView.showsVerticalScrollIndicator = false
  124. tableView.delegate = self
  125. tableView.dataSource = self
  126. tableView.tableViewNeverAdjustContentInset()
  127. tableView.bounces = false
  128. tableView.isUserInteractionEnabled = true
  129. tableView.isScrollEnabled = false
  130. tableView.contentInsetAdjustmentBehavior = .never
  131. tableView.register(cellClass: QSLHomeFriendTableViewCell.self)
  132. return tableView
  133. }()
  134. override init(frame: CGRect) {
  135. super.init(frame: frame)
  136. self.scrollCenterHeight = self.qsl_top
  137. self.scrollBottomHeight = qsl_kScreenH - qsl_kTabbarFrameH - 56 - 40
  138. self.setupUI()
  139. self.addPanAction()
  140. NotificationCenter.default.addObserver(
  141. self,
  142. selector: #selector(handleCouponNotification(_:)),
  143. name: Notification.Name("QSLHomeUpdateCouponViewNoti"),
  144. object: nil
  145. )
  146. //更新首页优惠券价格
  147. NotificationCenter.default.addObserver(
  148. self,
  149. selector: #selector(refreshCouponNotification(_:)),
  150. name: Notification.Name("QSLHomeRefreshCouponViewNoti"),
  151. object: nil
  152. )
  153. }
  154. required init?(coder: NSCoder) {
  155. fatalError("init(coder:) has not been implemented")
  156. }
  157. @objc func refreshBtnAction() {
  158. delegate?.refreshBtnAction()
  159. }
  160. }
  161. // MARK: - 设置UI
  162. extension QSLHomeFriendView {
  163. func setupUI() {
  164. addSubview(couponView)
  165. couponView.addSubview(couponBtn)
  166. couponView.addSubview(couponLabel)
  167. couponView.addSubview(countdownLabel)
  168. addSubview(friBgView)
  169. addSubview(friTableView)
  170. addSubview(friMapLogoImageView)
  171. addSubview(friExpandButton)
  172. addSubview(refreshButton)
  173. friBgView.addSubview(friHeaderView)
  174. friHeaderView.addSubview(friHeaderTitleIcon)
  175. friHeaderView.addSubview(friHeaderAddBtn)
  176. friMapLogoImageView.snp.makeConstraints { make in
  177. make.size.equalTo(CGSize(width: 62, height: 20))
  178. make.top.equalTo(0)
  179. make.left.equalTo(12)
  180. }
  181. friExpandButton.snp.makeConstraints { make in
  182. make.size.equalTo(CGSize(width: 80, height: 4))
  183. make.top.equalTo(friMapLogoImageView.snp.bottom).offset(8)
  184. make.centerX.equalTo(snp.centerX)
  185. }
  186. // couponView 的约束(初始时设为隐藏)
  187. couponView.snp.makeConstraints { make in
  188. make.left.equalTo(8.rpx)
  189. make.right.equalTo(-8.rpx)
  190. make.height.equalTo(58.rpx)
  191. couponViewTopConstraint = make.top.equalTo(friExpandButton.snp.bottom).offset(8.rpx).constraint
  192. }
  193. couponLabel.snp.makeConstraints { make in
  194. make.height.equalTo(22.rpx)
  195. make.top.equalTo(10.rpx)
  196. make.left.equalTo(60.rpx)
  197. make.right.equalTo(-12.rpx)
  198. }
  199. couponBtn.snp.makeConstraints { make in
  200. make.height.equalTo(28.rpx)
  201. make.width.equalTo(65.rpx)
  202. make.right.equalTo(-12.rpx)
  203. make.centerY.equalToSuperview()
  204. }
  205. countdownLabel.snp.makeConstraints { make in
  206. make.height.equalTo(17.rpx)
  207. make.top.equalTo(couponLabel.snp.bottom).offset(0)
  208. make.left.equalTo(60.rpx)
  209. make.right.equalTo(couponBtn.snp.left).offset(-10.rpx)
  210. }
  211. friBgView.snp.makeConstraints { make in
  212. friBgViewTopConstraint = make.top.equalTo(friExpandButton.snp.bottom).offset(8.rpx).constraint
  213. make.left.bottom.right.equalToSuperview()
  214. }
  215. refreshButton.snp.makeConstraints { make in
  216. make.size.equalTo(CGSize(width: 40.rpx, height: 40.rpx))
  217. make.right.equalTo(-8.rpx)
  218. make.bottom.equalTo(friBgView.snp.top).offset(-12.rpx)
  219. }
  220. friHeaderView.snp.makeConstraints { make in
  221. make.left.right.equalTo(0)
  222. make.height.equalTo(61.rpx)
  223. make.top.equalTo(0)
  224. }
  225. friHeaderTitleIcon.snp.makeConstraints { make in
  226. make.size.equalTo(CGSize(width: 82.rpx, height: 26.5.rpx))
  227. make.left.equalTo(16.rpx)
  228. make.top.equalTo(16.rpx)
  229. }
  230. friHeaderAddBtn.snp.makeConstraints { make in
  231. make.size.equalTo(CGSize(width: 106.rpx, height: 32.rpx))
  232. make.right.equalTo(-8.rpx)
  233. make.centerY.equalTo(friHeaderTitleIcon.snp.centerY)
  234. }
  235. friTableView.snp.makeConstraints { make in
  236. make.left.equalTo(0)
  237. make.right.equalTo(0)
  238. make.top.equalTo(friBgView.snp.top).offset(50.rpx)
  239. make.bottom.equalTo(-12.rpx)
  240. }
  241. }
  242. }
  243. // MARK: - 点击事件
  244. extension QSLHomeFriendView {
  245. @objc func unlockBtnAction(){
  246. gravityInstance?.track(QSLGravityConst.home_coupon_click, properties: [:])
  247. QSLJumpManager.shared.unlockBtnAction()
  248. }
  249. @objc func homeFriPhoneViewAction() {
  250. delegate?.homeFriPhoneViewClick()
  251. }
  252. @objc func topAddButtonAction() {
  253. delegate?.addFriendAction(isSmall: true)
  254. }
  255. }
  256. extension QSLHomeFriendView: QSLHomeFriendTableViewCellDelegate {
  257. func routeBtnAction(model: QSLUserModel) {
  258. delegate?.routeBtnAction(model: model)
  259. }
  260. func locateBtnAction(model: QSLUserModel) {
  261. delegate?.locateBtnAction(model: model)
  262. }
  263. @objc private func handleCouponNotification(_ notification: Notification) {
  264. guard let shouldShow = notification.userInfo?["showCoupon"] as? Bool else { return }
  265. updateCouponViewVisibility(show: shouldShow)
  266. }
  267. @objc private func refreshCouponNotification(_ notification: Notification) {
  268. refreshCouponView()
  269. }
  270. func refreshCouponView(){
  271. if let model = QSLCountdownManager.shared.selectGood {
  272. let amount : Int = Int((model.originalAmount - model.amount) / 100)
  273. let attr = NSMutableAttributedString()
  274. let firstText = "您有一订单未支付专属优惠券 "
  275. let firstAttr = NSMutableAttributedString(string: firstText)
  276. firstAttr.yy_font = UIFont.textM(10)
  277. firstAttr.yy_color = UIColor.white
  278. attr.append(firstAttr)
  279. if amount > 0 {
  280. let secondText = "-¥\(amount)"
  281. let secondAttr = NSMutableAttributedString(string: secondText)
  282. secondAttr.yy_font = UIFont.textB(18)
  283. secondAttr.yy_color = UIColor.hexStringColor(hexString: "#E1E3A3")
  284. attr.append(secondAttr)
  285. }
  286. self.couponLabel.attributedText = attr
  287. if(self.countdownLabel.label.text != nil){
  288. return
  289. }
  290. QSLCountdownManager.shared.updateHandler = { [weak self] timeString in
  291. if let curVC = self?.rootViewController(){
  292. if(curVC.isKind(of: QSLHomeController.self)){
  293. self?.countdownLabel.updateCountdownText(timeString)
  294. }
  295. }
  296. }
  297. QSLCountdownManager.shared.finishHandler = { [weak self] in
  298. self?.updateCouponViewVisibility(show: false)
  299. }
  300. QSLCountdownManager.shared.startCountdown()
  301. }
  302. }
  303. private func updateCouponViewVisibility(show: Bool) {
  304. if(couponView.isHidden == !show){
  305. self.refreshCouponView()
  306. return
  307. }
  308. couponView.isHidden = !show
  309. if (show) {
  310. self.refreshCouponView()
  311. couponViewTopConstraint?.update(offset: 8.rpx)
  312. friBgViewTopConstraint?.update(offset: 8.rpx) // 修改这里
  313. friBgView.snp.remakeConstraints { make in
  314. make.top.equalTo(couponView.snp.bottom).offset(0)
  315. make.left.bottom.right.equalToSuperview()
  316. }
  317. refreshButton.snp.remakeConstraints { make in
  318. make.size.equalTo(CGSize(width: 40.rpx, height: 40.rpx))
  319. make.right.equalTo(-8.rpx)
  320. make.bottom.equalTo(couponView.snp.top).offset(-12.rpx)
  321. }
  322. } else {
  323. couponViewTopConstraint?.update(offset: 0)
  324. friBgView.snp.remakeConstraints { make in
  325. make.top.equalTo(friExpandButton.snp.bottom).offset(8.rpx)
  326. make.left.bottom.right.equalToSuperview()
  327. }
  328. refreshButton.snp.remakeConstraints { make in
  329. make.size.equalTo(CGSize(width: 40.rpx, height: 40.rpx))
  330. make.right.equalTo(-8.rpx)
  331. make.bottom.equalTo(friBgView.snp.top).offset(-12.rpx)
  332. }
  333. }
  334. UIView.animate(withDuration: 0.3) {
  335. self.layoutIfNeeded()
  336. }
  337. }
  338. }
  339. // MARK: - 添加滑动逻辑
  340. extension QSLHomeFriendView: UIGestureRecognizerDelegate {
  341. func addPanAction() {
  342. let pan = UIPanGestureRecognizer(target: self, action: #selector(panAction))
  343. pan.delegate = self
  344. self.addGestureRecognizer(pan)
  345. }
  346. @objc func panAction(pan: UIPanGestureRecognizer) {
  347. let point = pan.translation(in: self)
  348. if let scrollStopY = self.scrollStopY, scrollStopY > 0 {
  349. pan.setTranslation(CGPoint(x: 0, y: 0), in: self)
  350. return
  351. }
  352. self.qsl_top += point.y
  353. if let scrollTopHeight = self.scrollTopHeight, self.qsl_top < scrollTopHeight {
  354. self.qsl_top = scrollTopHeight
  355. }
  356. if let scrollBottomHeight = self.scrollBottomHeight, self.qsl_top > scrollBottomHeight {
  357. self.qsl_top = scrollBottomHeight
  358. }
  359. if pan.state == .ended || pan.state == .cancelled {
  360. let velocity = pan.velocity(in: self)
  361. let speed = 350.0
  362. if let scrollLocation = self.scrollLocation {
  363. switch scrollLocation {
  364. case .ScrollTop:
  365. if velocity.y < -speed {
  366. self.scrollToLocation(type: .ScrollTop)
  367. pan.setTranslation(CGPoint(x: 0, y: 0), in: self)
  368. return
  369. } else if velocity.y > speed {
  370. self.scrollToLocation(type: .ScrollCenter)
  371. pan.setTranslation(CGPoint(x: 0, y: 0), in: self)
  372. return
  373. }
  374. break
  375. case .ScrollCenter:
  376. if velocity.y < -speed {
  377. self.scrollToLocation(type: .ScrollTop)
  378. pan.setTranslation(CGPoint(x: 0, y: 0), in: self)
  379. return
  380. } else if velocity.y > speed {
  381. self.scrollToLocation(type: .ScrollBottom)
  382. pan.setTranslation(CGPoint(x: 0, y: 0), in: self)
  383. return
  384. }
  385. break
  386. case .ScrollBottom:
  387. if velocity.y < -speed {
  388. self.scrollToLocation(type: .ScrollCenter)
  389. pan.setTranslation(CGPoint(x: 0, y: 0), in: self)
  390. return
  391. } else if velocity.y > speed {
  392. self.scrollToLocation(type: .ScrollBottom)
  393. pan.setTranslation(CGPoint(x: 0, y: 0), in: self)
  394. return
  395. }
  396. break
  397. }
  398. }
  399. if self.qsl_top < (qsl_kScreenH - qsl_kTabbarBottom) / 4 {
  400. self.scrollToLocation(type: .ScrollTop)
  401. } else if self.qsl_top < (qsl_kScreenH - qsl_kTabbarBottom) / 4 * 3 && self.qsl_top > (qsl_kScreenH - qsl_kTabbarBottom) / 4 {
  402. self.scrollToLocation(type: .ScrollCenter)
  403. } else {
  404. self.scrollToLocation(type: .ScrollBottom)
  405. }
  406. }
  407. pan.setTranslation(CGPoint(x: 0, y: 0), in: self)
  408. }
  409. func scrollToLocation(type: FriendViewLocation) {
  410. let animation = CASpringAnimation(keyPath: "position.y")
  411. animation.damping = 10
  412. animation.stiffness = 200
  413. animation.mass = 1
  414. animation.initialVelocity = 10
  415. animation.duration = animation.settlingDuration
  416. // animation.fromValue = self.friPhoneView.layer.position.y
  417. // animation.toValue = self.friPhoneView.layer.position.y + 2
  418. animation.isRemovedOnCompletion = false
  419. animation.fillMode = .forwards
  420. let animation1 = CASpringAnimation(keyPath: "position.y")
  421. animation1.damping = 10
  422. animation1.stiffness = 200
  423. animation1.mass = 1
  424. animation1.initialVelocity = 10
  425. animation1.duration = animation.settlingDuration
  426. animation1.fromValue = self.friTableView.layer.position.y
  427. animation1.toValue = self.friTableView.layer.position.y + 2
  428. animation1.isRemovedOnCompletion = false
  429. animation1.fillMode = .forwards
  430. self.scrollLocation = type
  431. if let topHeight = self.scrollTopHeight, let centerHeight = self.scrollCenterHeight, let bottomHeight = self.scrollBottomHeight {
  432. switch type {
  433. case .ScrollTop:
  434. UIView.animate(withDuration: 0.2) {
  435. self.qsl_top = topHeight
  436. } completion: { finished in
  437. self.friTableView.isScrollEnabled = true
  438. // self.friPhoneView.layer.add(animation, forKey: "animation")
  439. self.friTableView.layer.add(animation1, forKey: "animation")
  440. }
  441. break
  442. case .ScrollCenter:
  443. UIView.animate(withDuration: 0.2) {
  444. self.qsl_top = centerHeight
  445. } completion: { finished in
  446. self.friTableView.isScrollEnabled = false
  447. // self.friPhoneView.layer.add(animation, forKey: "animation")
  448. self.friTableView.layer.add(animation1, forKey: "animation")
  449. }
  450. break
  451. case .ScrollBottom:
  452. UIView.animate(withDuration: 0.2) {
  453. self.qsl_top = bottomHeight
  454. } completion: { finished in
  455. self.friTableView.isScrollEnabled = false
  456. // self.friPhoneView.layer.add(animation, forKey: "animation")
  457. self.friTableView.layer.add(animation1, forKey: "animation")
  458. }
  459. break
  460. }
  461. }
  462. delegate?.viewDidScroll()
  463. }
  464. func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
  465. return true
  466. }
  467. func scrollViewDidScroll(_ scrollView: UIScrollView) {
  468. let currentPostion = scrollView.contentOffset.y
  469. self.scrollStopY = currentPostion
  470. }
  471. }
  472. extension QSLHomeFriendView: QSLHomeFriendFooterViewDelegate {
  473. func addButtonAction() {
  474. delegate?.addFriendAction(isSmall: false)
  475. }
  476. }
  477. // MARK: - 设置Tableview
  478. extension QSLHomeFriendView: UITableViewDelegate, UITableViewDataSource {
  479. func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  480. guard let friendList = viewModel?.friendList else { return 0 }
  481. return friendList.count
  482. }
  483. func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
  484. // if indexPath.row == 0 {
  485. //
  486. // cell.addCorner(conrners: [.topRight, .topLeft], radius: 6)
  487. // }
  488. //
  489. // if let friendList = viewModel?.friendList, indexPath.row == friendList.count - 1 {
  490. //
  491. // cell.addCorner(conrners: [.bottomLeft, .bottomRight], radius: 6)
  492. // }
  493. }
  494. func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  495. let cell = tableView.dequeueReusableCell(cellType: QSLHomeFriendTableViewCell.self, cellForRowAt: indexPath)
  496. cell.selectionStyle = .none
  497. cell.delegate = self
  498. if let model = viewModel?.friendList[indexPath.row] {
  499. cell.config(model: model)
  500. }
  501. return cell
  502. }
  503. func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
  504. return 94.rpx
  505. }
  506. func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
  507. return 0.0001
  508. }
  509. func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
  510. return 200.rpx
  511. }
  512. func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
  513. let view = QSLHomeFriendFooterView()
  514. view.delegate = self
  515. return view
  516. }
  517. }