QSLHomeFriendView.swift 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757
  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. var countDownType = 0
  44. lazy var friMapLogoImageView: UIImageView = {
  45. let imageView = UIImageView()
  46. imageView.isHidden = true
  47. imageView.image = UIImage(named: "home_friends_map_logo")
  48. return imageView
  49. }()
  50. lazy var friExpandButton: UIButton = {
  51. let button = UIButton(type: .custom)
  52. button.backgroundColor = UIColor.hexStringColor(hexString: "#333333", alpha: 0.6)
  53. button.addRadius(radius: 2)
  54. return button
  55. }()
  56. lazy var refreshButton: UIButton = {
  57. let button = UIButton(type: .custom)
  58. button.setBackgroundImage(UIImage(named: "home_refresh_btn"), for: .normal)
  59. button.addTarget(self, action: #selector(refreshBtnAction), for: .touchUpInside)
  60. return button
  61. }()
  62. lazy var couponView: UIImageView = {
  63. let view = UIImageView()
  64. view.image = UIImage(named: "home_activity_bg")
  65. view.isUserInteractionEnabled = true
  66. view.isHidden = true
  67. let tapG = UITapGestureRecognizer.init(target: self, action: #selector(unlockBtnAction))
  68. view.addGestureRecognizer(tapG)
  69. return view
  70. }()
  71. lazy var couponLabel: YYLabel = {
  72. let label = YYLabel()
  73. return label
  74. }()
  75. lazy var countdownLabel: QSLCountdownView = {
  76. let label = QSLCountdownView(frame: CGRectMake(0, 0, QSLConst.qsl_kScreenW - 24.rpx, 17.rpx),type: 1)
  77. return label
  78. }()
  79. lazy var couponBtn: UILabel = {
  80. let label = UILabel()
  81. label.gradientBackgroundColor(color1: UIColor.hexStringColor(hexString: "#FFFEF3", alpha: 1), color2: UIColor.hexStringColor(hexString: "#FFE6C0", alpha: 1), width: 65.rpx, height: 28.rpx, direction: .horizontal)
  82. label.text("去使用")
  83. label.textAlignment = .center
  84. label.font = UIFont.textM(14)
  85. label.textColor = (UIColor.hexStringColor(hexString: "#3A331C"))
  86. label.addRadius(radius: 14.rpx)
  87. return label
  88. }()
  89. lazy var friBgView: UIView = {
  90. let view = UIView()
  91. view.clipsToBounds = true
  92. view.backgroundColor = QSLColor.backGroundColor
  93. view.addRadius(radius: 12.rpx)
  94. return view
  95. }()
  96. lazy var friHeaderView: UIView = {
  97. let view = UIView(frame: CGRect(x: 0, y: 0, width: QSLConst.qsl_kScreenW, height: 61.rpx))
  98. 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) {
  99. view.backgroundColor = UIColor(patternImage: image)
  100. }
  101. view.addFourCorner(topLeft: 12.rpx, topRight: 12.rpx, bottomLeft: 0, bottomRight: 0)
  102. return view
  103. }()
  104. lazy var friHeaderTitleIcon: UIImageView = {
  105. let imageView = UIImageView()
  106. imageView.image = UIImage(named: "home_friends_header_title")
  107. return imageView
  108. }()
  109. lazy var friHeaderAddBtn: UIButton = {
  110. let btn = UIButton()
  111. btn.setBackgroundImage(UIImage(named: "home_friends_header_add_btn_bg"), for: .normal)
  112. btn.image(UIImage(named: "home_friends_header_add_icon"))
  113. btn.title(QSLConfig.addFriendTitle)
  114. btn.mediumFont(15)
  115. btn.textColor(.white)
  116. btn.setImageTitleLayout(.imgLeft, spacing: 0)
  117. btn.addTarget(self, action: #selector(topAddButtonAction), for: .touchUpInside)
  118. return btn
  119. }()
  120. lazy var friTableView: UITableView = {
  121. let tableView = UITableView(frame: .zero, style: .grouped)
  122. tableView.backgroundColor = .clear
  123. tableView.separatorStyle = .none
  124. tableView.showsVerticalScrollIndicator = false
  125. tableView.delegate = self
  126. tableView.dataSource = self
  127. tableView.tableViewNeverAdjustContentInset()
  128. tableView.bounces = false
  129. tableView.isUserInteractionEnabled = true
  130. tableView.isScrollEnabled = false
  131. tableView.contentInsetAdjustmentBehavior = .never
  132. tableView.register(cellClass: QSLHomeFriendTableViewCell.self)
  133. return tableView
  134. }()
  135. override init(frame: CGRect) {
  136. super.init(frame: frame)
  137. QSLCountdownManager.shared.addDelegate(self)
  138. self.scrollCenterHeight = self.qsl_top
  139. self.scrollBottomHeight = qsl_kScreenH - qsl_kTabbarFrameH - 56 - 40
  140. self.setupUI()
  141. self.addPanAction()
  142. NotificationCenter.default.addObserver(
  143. self,
  144. selector: #selector(handleCouponNotification(_:)),
  145. name: Notification.Name("QSLHomeUpdateCouponViewNoti"),
  146. object: nil
  147. )
  148. //更新首页优惠券价格
  149. NotificationCenter.default.addObserver(
  150. self,
  151. selector: #selector(refreshCouponNotification(_:)),
  152. name: Notification.Name("QSLHomeRefreshCouponViewNoti"),
  153. object: nil
  154. )
  155. }
  156. required init?(coder: NSCoder) {
  157. fatalError("init(coder:) has not been implemented")
  158. }
  159. @objc func refreshBtnAction() {
  160. delegate?.refreshBtnAction()
  161. }
  162. }
  163. // MARK: - 设置UI
  164. extension QSLHomeFriendView {
  165. func setupUI() {
  166. addSubview(couponView)
  167. couponView.addSubview(couponBtn)
  168. couponView.addSubview(couponLabel)
  169. couponView.addSubview(countdownLabel)
  170. addSubview(friBgView)
  171. addSubview(friTableView)
  172. addSubview(friMapLogoImageView)
  173. addSubview(friExpandButton)
  174. addSubview(refreshButton)
  175. friBgView.addSubview(friHeaderView)
  176. friHeaderView.addSubview(friHeaderTitleIcon)
  177. friHeaderView.addSubview(friHeaderAddBtn)
  178. friMapLogoImageView.snp.makeConstraints { make in
  179. make.size.equalTo(CGSize(width: 62, height: 20))
  180. make.top.equalTo(0)
  181. make.left.equalTo(12)
  182. }
  183. friExpandButton.snp.makeConstraints { make in
  184. make.size.equalTo(CGSize(width: 80, height: 4))
  185. make.top.equalTo(friMapLogoImageView.snp.bottom).offset(8)
  186. make.centerX.equalTo(snp.centerX)
  187. }
  188. // couponView 的约束(初始时设为隐藏)
  189. couponView.snp.makeConstraints { make in
  190. make.left.equalTo(8.rpx)
  191. make.right.equalTo(-8.rpx)
  192. make.height.equalTo(58.rpx)
  193. couponViewTopConstraint = make.top.equalTo(friExpandButton.snp.bottom).offset(8.rpx).constraint
  194. }
  195. couponLabel.snp.makeConstraints { make in
  196. make.height.equalTo(22.rpx)
  197. make.top.equalTo(10.rpx)
  198. make.left.equalTo(60.rpx)
  199. make.right.equalTo(-12.rpx)
  200. }
  201. couponBtn.snp.makeConstraints { make in
  202. make.height.equalTo(28.rpx)
  203. make.width.equalTo(65.rpx)
  204. make.right.equalTo(-12.rpx)
  205. make.centerY.equalToSuperview()
  206. }
  207. countdownLabel.snp.makeConstraints { make in
  208. make.height.equalTo(17.rpx)
  209. make.top.equalTo(couponLabel.snp.bottom).offset(0)
  210. make.left.equalTo(60.rpx)
  211. make.right.equalTo(couponBtn.snp.left).offset(-10.rpx)
  212. }
  213. friBgView.snp.makeConstraints { make in
  214. friBgViewTopConstraint = make.top.equalTo(friExpandButton.snp.bottom).offset(8.rpx).constraint
  215. make.left.bottom.right.equalToSuperview()
  216. }
  217. refreshButton.snp.makeConstraints { make in
  218. make.size.equalTo(CGSize(width: 40.rpx, height: 40.rpx))
  219. make.right.equalTo(-8.rpx)
  220. make.bottom.equalTo(friBgView.snp.top).offset(-12.rpx)
  221. }
  222. friHeaderView.snp.makeConstraints { make in
  223. make.left.right.equalTo(0)
  224. make.height.equalTo(61.rpx)
  225. make.top.equalTo(0)
  226. }
  227. friHeaderTitleIcon.snp.makeConstraints { make in
  228. make.size.equalTo(CGSize(width: 82.rpx, height: 26.5.rpx))
  229. make.left.equalTo(16.rpx)
  230. make.top.equalTo(16.rpx)
  231. }
  232. friHeaderAddBtn.snp.makeConstraints { make in
  233. make.size.equalTo(CGSize(width: 106.rpx, height: 32.rpx))
  234. make.right.equalTo(-8.rpx)
  235. make.centerY.equalTo(friHeaderTitleIcon.snp.centerY)
  236. }
  237. friTableView.snp.makeConstraints { make in
  238. make.left.equalTo(0)
  239. make.right.equalTo(0)
  240. make.top.equalTo(friBgView.snp.top).offset(50.rpx)
  241. make.bottom.equalTo(-12.rpx)
  242. }
  243. }
  244. }
  245. // MARK: - 点击事件
  246. extension QSLHomeFriendView {
  247. @objc func unlockBtnAction(){
  248. if(countDownType == 1){
  249. QSEventHandle.eventPush(eventName: QSLGravityConst.activity_page_click, eventProps: ["page_type":"coupon_popup"])
  250. QSLJumpManager.shared.unlockTrialBtnAction()
  251. }else{
  252. QSEventHandle.eventPush(eventName: QSLGravityConst.home_coupon_click)
  253. QSLJumpManager.shared.unlockBtnAction()
  254. }
  255. }
  256. @objc func homeFriPhoneViewAction() {
  257. delegate?.homeFriPhoneViewClick()
  258. }
  259. @objc func topAddButtonAction() {
  260. delegate?.addFriendAction(isSmall: true)
  261. }
  262. }
  263. extension QSLHomeFriendView: QSLHomeFriendTableViewCellDelegate {
  264. func routeBtnAction(model: QSLUserModel) {
  265. delegate?.routeBtnAction(model: model)
  266. }
  267. func locateBtnAction(model: QSLUserModel) {
  268. delegate?.locateBtnAction(model: model)
  269. }
  270. @objc private func handleCouponNotification(_ notification: Notification) {
  271. guard let shouldShow = notification.userInfo?["showCoupon"] as? Bool else { return }
  272. if ((notification.userInfo?["couponType"]) != nil){
  273. updateCouponViewVisibility(show: shouldShow, showType: 1)
  274. }else{
  275. updateCouponViewVisibility(show: shouldShow)
  276. }
  277. }
  278. @objc private func refreshCouponNotification(_ notification: Notification) {
  279. refreshCouponView()
  280. }
  281. func refreshCouponView(type: Int = 0){
  282. if(type == 1){
  283. if let model = QSLCountdownManager.shared.trialGood {
  284. let attr = NSMutableAttributedString()
  285. let firstText = "您有 "
  286. let firstAttr = NSMutableAttributedString(string: firstText)
  287. firstAttr.yy_font = UIFont.textM(10)
  288. firstAttr.yy_color = UIColor.white
  289. attr.append(firstAttr)
  290. let secondText = "免费专属试用"
  291. let secondAttr = NSMutableAttributedString(string: secondText)
  292. secondAttr.yy_font = UIFont.textB(14)
  293. secondAttr.yy_color = UIColor.hexStringColor(hexString: "#E1E3A3")
  294. attr.append(secondAttr)
  295. let thirdAttr = NSMutableAttributedString(string: " 福利未领取")
  296. thirdAttr.yy_font = UIFont.textM(10)
  297. thirdAttr.yy_color = UIColor.white
  298. attr.append(thirdAttr)
  299. self.couponLabel.attributedText = attr
  300. if(countDownType == 1){
  301. return
  302. }
  303. couponView.image = UIImage(named: "home_trial_bg")
  304. couponLabel.snp.updateConstraints { make in
  305. make.left.equalTo(20.rpx)
  306. }
  307. countdownLabel.snp.updateConstraints { make in
  308. make.left.equalTo(20.rpx)
  309. }
  310. countDownType = 1
  311. // 开始首页商品倒计时
  312. QSLCountdownManager.shared.startCountdown(type: .trial, seconds: 900000) { remainingSeconds in
  313. } finishCallback: {
  314. }
  315. }
  316. return
  317. }
  318. if let model = QSLCountdownManager.shared.selectGood {
  319. let amount : Int = Int((model.originalAmount - model.amount) / 100)
  320. let attr = NSMutableAttributedString()
  321. let firstText = "您有一订单未支付专属优惠券 "
  322. let firstAttr = NSMutableAttributedString(string: firstText)
  323. firstAttr.yy_font = UIFont.textM(10)
  324. firstAttr.yy_color = UIColor.white
  325. attr.append(firstAttr)
  326. if amount > 0 {
  327. let secondText = "-¥\(amount)"
  328. let secondAttr = NSMutableAttributedString(string: secondText)
  329. secondAttr.yy_font = UIFont.textB(18)
  330. secondAttr.yy_color = UIColor.hexStringColor(hexString: "#E1E3A3")
  331. attr.append(secondAttr)
  332. }
  333. self.couponLabel.attributedText = attr
  334. if(countDownType == 0){
  335. return
  336. }
  337. countDownType = 0
  338. couponLabel.snp.updateConstraints { make in
  339. make.left.equalTo(60.rpx)
  340. }
  341. countdownLabel.snp.updateConstraints { make in
  342. make.left.equalTo(60.rpx)
  343. }
  344. QSLCountdownManager.shared.startCountdown(type: .homeProduct, seconds: 900000) {[weak self] remainingSeconds in
  345. } finishCallback: {
  346. }
  347. couponView.image = UIImage(named: "home_activity_bg")
  348. }
  349. }
  350. private func updateCouponViewVisibility(show: Bool, showType:Int = 0) {
  351. if(couponView.isHidden == !show){
  352. self.refreshCouponView(type: showType)
  353. return
  354. }
  355. couponView.isHidden = !show
  356. if (show) {
  357. self.refreshCouponView(type: showType)
  358. couponViewTopConstraint?.update(offset: 8.rpx)
  359. friBgViewTopConstraint?.update(offset: 8.rpx) // 修改这里
  360. friBgView.snp.remakeConstraints { make in
  361. make.top.equalTo(couponView.snp.bottom).offset(0)
  362. make.left.bottom.right.equalToSuperview()
  363. }
  364. refreshButton.snp.remakeConstraints { make in
  365. make.size.equalTo(CGSize(width: 40.rpx, height: 40.rpx))
  366. make.right.equalTo(-8.rpx)
  367. make.bottom.equalTo(couponView.snp.top).offset(-12.rpx)
  368. }
  369. } else {
  370. couponViewTopConstraint?.update(offset: 0)
  371. friBgView.snp.remakeConstraints { make in
  372. make.top.equalTo(friExpandButton.snp.bottom).offset(8.rpx)
  373. make.left.bottom.right.equalToSuperview()
  374. }
  375. refreshButton.snp.remakeConstraints { make in
  376. make.size.equalTo(CGSize(width: 40.rpx, height: 40.rpx))
  377. make.right.equalTo(-8.rpx)
  378. make.bottom.equalTo(friBgView.snp.top).offset(-12.rpx)
  379. }
  380. }
  381. UIView.animate(withDuration: 0.3) {
  382. self.layoutIfNeeded()
  383. }
  384. }
  385. }
  386. // MARK: - 添加滑动逻辑
  387. extension QSLHomeFriendView: UIGestureRecognizerDelegate {
  388. func addPanAction() {
  389. let pan = UIPanGestureRecognizer(target: self, action: #selector(panAction))
  390. pan.delegate = self
  391. self.addGestureRecognizer(pan)
  392. }
  393. @objc func panAction(pan: UIPanGestureRecognizer) {
  394. let point = pan.translation(in: self)
  395. if let scrollStopY = self.scrollStopY, scrollStopY > 0 {
  396. pan.setTranslation(CGPoint(x: 0, y: 0), in: self)
  397. return
  398. }
  399. self.qsl_top += point.y
  400. if let scrollTopHeight = self.scrollTopHeight, self.qsl_top < scrollTopHeight {
  401. self.qsl_top = scrollTopHeight
  402. }
  403. if let scrollBottomHeight = self.scrollBottomHeight, self.qsl_top > scrollBottomHeight {
  404. self.qsl_top = scrollBottomHeight
  405. }
  406. if pan.state == .ended || pan.state == .cancelled {
  407. let velocity = pan.velocity(in: self)
  408. let speed = 350.0
  409. if let scrollLocation = self.scrollLocation {
  410. switch scrollLocation {
  411. case .ScrollTop:
  412. if velocity.y < -speed {
  413. self.scrollToLocation(type: .ScrollTop)
  414. pan.setTranslation(CGPoint(x: 0, y: 0), in: self)
  415. return
  416. } else if velocity.y > speed {
  417. self.scrollToLocation(type: .ScrollCenter)
  418. pan.setTranslation(CGPoint(x: 0, y: 0), in: self)
  419. return
  420. }
  421. break
  422. case .ScrollCenter:
  423. if velocity.y < -speed {
  424. self.scrollToLocation(type: .ScrollTop)
  425. pan.setTranslation(CGPoint(x: 0, y: 0), in: self)
  426. return
  427. } else if velocity.y > speed {
  428. self.scrollToLocation(type: .ScrollBottom)
  429. pan.setTranslation(CGPoint(x: 0, y: 0), in: self)
  430. return
  431. }
  432. break
  433. case .ScrollBottom:
  434. if velocity.y < -speed {
  435. self.scrollToLocation(type: .ScrollCenter)
  436. pan.setTranslation(CGPoint(x: 0, y: 0), in: self)
  437. return
  438. } else if velocity.y > speed {
  439. self.scrollToLocation(type: .ScrollBottom)
  440. pan.setTranslation(CGPoint(x: 0, y: 0), in: self)
  441. return
  442. }
  443. break
  444. }
  445. }
  446. if self.qsl_top < (qsl_kScreenH - qsl_kTabbarBottom) / 4 {
  447. self.scrollToLocation(type: .ScrollTop)
  448. } else if self.qsl_top < (qsl_kScreenH - qsl_kTabbarBottom) / 4 * 3 && self.qsl_top > (qsl_kScreenH - qsl_kTabbarBottom) / 4 {
  449. self.scrollToLocation(type: .ScrollCenter)
  450. } else {
  451. self.scrollToLocation(type: .ScrollBottom)
  452. }
  453. }
  454. pan.setTranslation(CGPoint(x: 0, y: 0), in: self)
  455. }
  456. func scrollToLocation(type: FriendViewLocation) {
  457. let animation = CASpringAnimation(keyPath: "position.y")
  458. animation.damping = 10
  459. animation.stiffness = 200
  460. animation.mass = 1
  461. animation.initialVelocity = 10
  462. animation.duration = animation.settlingDuration
  463. // animation.fromValue = self.friPhoneView.layer.position.y
  464. // animation.toValue = self.friPhoneView.layer.position.y + 2
  465. animation.isRemovedOnCompletion = false
  466. animation.fillMode = .forwards
  467. let animation1 = CASpringAnimation(keyPath: "position.y")
  468. animation1.damping = 10
  469. animation1.stiffness = 200
  470. animation1.mass = 1
  471. animation1.initialVelocity = 10
  472. animation1.duration = animation.settlingDuration
  473. animation1.fromValue = self.friTableView.layer.position.y
  474. animation1.toValue = self.friTableView.layer.position.y + 2
  475. animation1.isRemovedOnCompletion = false
  476. animation1.fillMode = .forwards
  477. self.scrollLocation = type
  478. if let topHeight = self.scrollTopHeight, let centerHeight = self.scrollCenterHeight, let bottomHeight = self.scrollBottomHeight {
  479. switch type {
  480. case .ScrollTop:
  481. UIView.animate(withDuration: 0.2) {
  482. self.qsl_top = topHeight
  483. } completion: { finished in
  484. self.friTableView.isScrollEnabled = true
  485. // self.friPhoneView.layer.add(animation, forKey: "animation")
  486. self.friTableView.layer.add(animation1, forKey: "animation")
  487. }
  488. break
  489. case .ScrollCenter:
  490. UIView.animate(withDuration: 0.2) {
  491. self.qsl_top = centerHeight
  492. } completion: { finished in
  493. self.friTableView.isScrollEnabled = false
  494. // self.friPhoneView.layer.add(animation, forKey: "animation")
  495. self.friTableView.layer.add(animation1, forKey: "animation")
  496. }
  497. break
  498. case .ScrollBottom:
  499. UIView.animate(withDuration: 0.2) {
  500. self.qsl_top = bottomHeight
  501. } completion: { finished in
  502. self.friTableView.isScrollEnabled = false
  503. // self.friPhoneView.layer.add(animation, forKey: "animation")
  504. self.friTableView.layer.add(animation1, forKey: "animation")
  505. }
  506. break
  507. }
  508. }
  509. delegate?.viewDidScroll()
  510. }
  511. func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
  512. return true
  513. }
  514. func scrollViewDidScroll(_ scrollView: UIScrollView) {
  515. let currentPostion = scrollView.contentOffset.y
  516. self.scrollStopY = currentPostion
  517. }
  518. }
  519. extension QSLHomeFriendView: QSLHomeFriendFooterViewDelegate {
  520. func addButtonAction() {
  521. delegate?.addFriendAction(isSmall: false)
  522. }
  523. }
  524. // MARK: - 设置Tableview
  525. extension QSLHomeFriendView: UITableViewDelegate, UITableViewDataSource {
  526. func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  527. guard let friendList = viewModel?.friendList else { return 0 }
  528. return friendList.count
  529. }
  530. func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
  531. // if indexPath.row == 0 {
  532. //
  533. // cell.addCorner(conrners: [.topRight, .topLeft], radius: 6)
  534. // }
  535. //
  536. // if let friendList = viewModel?.friendList, indexPath.row == friendList.count - 1 {
  537. //
  538. // cell.addCorner(conrners: [.bottomLeft, .bottomRight], radius: 6)
  539. // }
  540. }
  541. func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  542. let cell = tableView.dequeueReusableCell(cellType: QSLHomeFriendTableViewCell.self, cellForRowAt: indexPath)
  543. cell.selectionStyle = .none
  544. cell.delegate = self
  545. if let model = viewModel?.friendList[indexPath.row] {
  546. cell.config(model: model)
  547. }
  548. return cell
  549. }
  550. func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
  551. return 94.rpx
  552. }
  553. func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
  554. return 0.0001
  555. }
  556. func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
  557. return 200.rpx
  558. }
  559. func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
  560. let view = QSLHomeFriendFooterView()
  561. view.delegate = self
  562. return view
  563. }
  564. }
  565. extension QSLHomeFriendView : QSLCountdownManagerDelegate{
  566. func countdownManager(_ manager: QSLCountdownManager, didUpdateCountdown type: QSLCountdownType, remainingSeconds: Int) {
  567. // 处理倒计时更新
  568. if type == .homeProduct && self.countDownType == 0{
  569. let totalSeconds = remainingSeconds / 1000
  570. let minutes = totalSeconds / 60
  571. let seconds = totalSeconds % 60
  572. var milliseconds = remainingSeconds % 1000
  573. if(milliseconds <= 1){
  574. milliseconds = 0
  575. }
  576. // 格式:MM:SS:SSS(例如 "14:59:500")
  577. let timeString = String(format: "%02d : %02d : %03d", minutes, seconds, milliseconds)
  578. self.countdownLabel.updateCountdownText(timeString)
  579. }
  580. if type == .trial && self.countDownType == 1{
  581. let totalSeconds = remainingSeconds / 1000
  582. let minutes = totalSeconds / 60
  583. let seconds = totalSeconds % 60
  584. var milliseconds = remainingSeconds % 1000
  585. if(milliseconds <= 1){
  586. milliseconds = 0
  587. }
  588. // 格式:MM:SS:SSS(例如 "14:59:500")
  589. let timeString = String(format: "%02d : %02d : %03d", minutes, seconds, milliseconds)
  590. self.countdownLabel.updateCountdownText(timeString)
  591. }
  592. }
  593. func countdownManager(_ manager: QSLCountdownManager, didFinishCountdown type: QSLCountdownType) {
  594. // 处理倒计时结束
  595. if type == .homeProduct && self.countDownType == 0{
  596. self.updateCouponViewVisibility(show: false)
  597. }
  598. if type == .trial && self.countDownType == 1{
  599. self.updateCouponViewVisibility(show: false)
  600. }
  601. }
  602. }