LNUserRelationViewController.swift 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. //
  2. // LNUserRelationViewController.swift
  3. // Lanu
  4. //
  5. // Created by OneeChan on 2025/12/19.
  6. //
  7. import Foundation
  8. import UIKit
  9. import SnapKit
  10. extension UIView {
  11. func pushToRelationList(uid: String, tabType: LNUserRelationTabType = .follow) {
  12. let vc = LNUserRelationViewController()
  13. navigationController?.pushViewController(vc, animated: true)
  14. vc.locatedTo(tabType)
  15. }
  16. }
  17. enum LNUserRelationTabType: CaseIterable {
  18. case follow
  19. case fans
  20. }
  21. class LNUserRelationViewController: LNViewController {
  22. private var curTabType: LNUserRelationTabType = .follow {
  23. didSet {
  24. locatedTabTo(curTabType, animated: true)
  25. }
  26. }
  27. private let tabIndicator = UIImageView()
  28. private let followLabel = UILabel()
  29. private let fansLabel = UILabel()
  30. private let scrollView = UIScrollView()
  31. private let followList = LNUserRelationListView(curType: .follow)
  32. private let fansList = LNUserRelationListView(curType: .fans)
  33. override func viewDidLoad() {
  34. super.viewDidLoad()
  35. setupViews()
  36. let tabType = curTabType
  37. curTabType = tabType
  38. }
  39. func locatedTo(_ tab: LNUserRelationTabType) {
  40. view.layoutIfNeeded()
  41. curTabType = tab
  42. }
  43. }
  44. extension LNUserRelationViewController: LNUserRelationListViewDelegate {
  45. func onUserRelationListViewTotalChanged(view: LNUserRelationListView, total: Int) {
  46. switch view.curType {
  47. case .fans:
  48. fansLabel.text = .init(key: "A00234", total)
  49. case .follow:
  50. followLabel.text = .init(key: "A00238", total)
  51. }
  52. }
  53. }
  54. extension LNUserRelationViewController: UIScrollViewDelegate {
  55. func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
  56. let page = Int(scrollView.contentOffset.x / scrollView.bounds.width)
  57. let tab = LNUserRelationTabType.allCases[page]
  58. locatedTabTo(tab, animated: true)
  59. }
  60. }
  61. extension LNUserRelationViewController {
  62. private func scrollTo(_ tab: LNUserRelationTabType, animated: Bool) {
  63. let page = LNUserRelationTabType.allCases.firstIndex(of: tab) ?? 0
  64. let offsetX = scrollView.bounds.width * CGFloat(page)
  65. scrollView.setContentOffset(.init(x: offsetX, y: 0), animated: animated)
  66. }
  67. private func locatedTabTo(_ tab: LNUserRelationTabType, animated: Bool) {
  68. let targetTab: UIView?
  69. switch tab {
  70. case .follow:
  71. targetTab = followLabel.superview
  72. followLabel.textColor = .text_5
  73. fansLabel.textColor = .text_2
  74. case .fans:
  75. targetTab = fansLabel.superview
  76. followLabel.textColor = .text_2
  77. fansLabel.textColor = .text_5
  78. }
  79. guard let targetTab else { return }
  80. tabIndicator.snp.remakeConstraints { make in
  81. make.center.equalTo(targetTab)
  82. make.height.equalTo(16)
  83. }
  84. scrollTo(tab, animated: animated)
  85. if animated {
  86. UIView.animate(withDuration: 0.25) { [weak self] in
  87. guard let self else { return }
  88. followLabel.superview?.superview?.layoutIfNeeded()
  89. }
  90. }
  91. }
  92. private func setupViews() {
  93. setupNavBar()
  94. scrollView.delegate = self
  95. scrollView.isPagingEnabled = true
  96. scrollView.showsVerticalScrollIndicator = false
  97. scrollView.showsHorizontalScrollIndicator = false
  98. view.addSubview(scrollView)
  99. scrollView.snp.makeConstraints { make in
  100. make.horizontalEdges.equalToSuperview()
  101. make.bottom.equalToSuperview()
  102. make.top.equalToSuperview()
  103. }
  104. followList.delegate = self
  105. scrollView.addSubview(followList)
  106. followList.snp.makeConstraints { make in
  107. make.verticalEdges.equalToSuperview()
  108. make.leading.equalToSuperview()
  109. make.width.height.equalToSuperview()
  110. }
  111. fansList.delegate = self
  112. scrollView.addSubview(fansList)
  113. fansList.snp.makeConstraints { make in
  114. make.verticalEdges.equalToSuperview()
  115. make.trailing.equalToSuperview()
  116. make.leading.equalTo(followList.snp.trailing)
  117. make.width.height.equalToSuperview()
  118. }
  119. }
  120. private func setupNavBar() {
  121. let stackView = UIStackView()
  122. stackView.axis = .horizontal
  123. stackView.spacing = 0
  124. stackView.distribution = .fillEqually
  125. setTitleView(stackView)
  126. stackView.snp.makeConstraints { make in
  127. make.width.equalTo(view.bounds.width).priority(.medium)
  128. make.height.equalTo(44)
  129. }
  130. tabIndicator.image = .icHomeTabSelected
  131. tabIndicator.contentMode = .scaleAspectFit
  132. stackView.addSubview(tabIndicator)
  133. let followButton = UIButton()
  134. followButton.addAction(UIAction(handler: { [weak self] _ in
  135. guard let self else { return }
  136. curTabType = .follow
  137. }), for: .touchUpInside)
  138. stackView.addArrangedSubview(followButton)
  139. followLabel.font = .heading_h3
  140. followLabel.textColor = .text_5
  141. followLabel.text = .init(key: "A00238", 0)
  142. followButton.addSubview(followLabel)
  143. followLabel.snp.makeConstraints { make in
  144. make.center.equalToSuperview()
  145. }
  146. let fansButton = UIButton()
  147. fansButton.addAction(UIAction(handler: { [weak self] _ in
  148. guard let self else { return }
  149. curTabType = .fans
  150. }), for: .touchUpInside)
  151. stackView.addArrangedSubview(fansButton)
  152. fansLabel.font = .heading_h3
  153. fansLabel.textColor = .text_5
  154. fansLabel.text = .init(key: "A00234", 0)
  155. fansButton.addSubview(fansLabel)
  156. fansLabel.snp.makeConstraints { make in
  157. make.center.equalToSuperview()
  158. }
  159. }
  160. }