LNRoomSeatApplyListPanel.swift 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. //
  2. // LNRoomSeatApplyListPanel.swift
  3. // Gami
  4. //
  5. // Created by OneeChan on 2026/3/13.
  6. //
  7. import Foundation
  8. import UIKit
  9. import SnapKit
  10. enum LNRoomSeatApplyTabType: Int, CaseIterable {
  11. case guest
  12. case playmate
  13. }
  14. class LNRoomSeatApplyListPanel: LNPopupView {
  15. private let tabBackgroundView = UIView()
  16. private let guestTabButton = UIButton()
  17. private let playmateTabButton = UIButton()
  18. private let tabSelectionView = UIView()
  19. private let countLabel = UILabel()
  20. private let countDescLabel = UILabel()
  21. private let filterButton = UIButton()
  22. private let tableView = UITableView(frame: .zero, style: .plain)
  23. private var guestItems: [LNRoomSeatApplyItem] = []
  24. private var playmateItems: [LNRoomSeatApplyItem] = []
  25. private var playmateCategoryTitle: String = "所有品类"
  26. private weak var roomSession: LNRoomViewModel?
  27. private var curTab: LNRoomSeatApplyTabType = .guest {
  28. didSet {
  29. guard oldValue != curTab else { return }
  30. reloadData()
  31. }
  32. }
  33. override init(frame: CGRect) {
  34. super.init(frame: frame)
  35. containerHeight = .percent(0.62)
  36. setupViews()
  37. }
  38. func update(_ room: LNRoomViewModel?) {
  39. roomSession = room
  40. }
  41. required init?(coder: NSCoder) {
  42. fatalError("init(coder:) has not been implemented")
  43. }
  44. }
  45. extension LNRoomSeatApplyListPanel: UITableViewDataSource, UITableViewDelegate {
  46. func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  47. currentItems.count
  48. }
  49. func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  50. let cell = tableView.dequeueReusableCell(
  51. withIdentifier: LNRoomSeatApplyListCell.className,
  52. for: indexPath
  53. ) as! LNRoomSeatApplyListCell
  54. let item = currentItems[indexPath.row]
  55. cell.update(room: roomSession, item: item, index: indexPath.row + 1)
  56. return cell
  57. }
  58. func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
  59. 64
  60. }
  61. }
  62. extension LNRoomSeatApplyListPanel {
  63. private var currentItems: [LNRoomSeatApplyItem] {
  64. switch curTab {
  65. case .guest: guestItems
  66. case .playmate: playmateItems
  67. }
  68. }
  69. private func reloadData() {
  70. updateTabs()
  71. countLabel.text = .init(key: "A00334", currentItems.count)
  72. filterButton.isHidden = curTab != .playmate
  73. filterButton.setTitle(playmateCategoryTitle, for: .normal)
  74. tableView.reloadData()
  75. }
  76. private func updateTabs() {
  77. let normalColor = UIColor.text_2
  78. let selectedColor = UIColor.text_5
  79. let selectedButton = curTab == .guest ? guestTabButton : playmateTabButton
  80. guestTabButton.setTitleColor(curTab == .guest ? selectedColor : normalColor, for: .normal)
  81. playmateTabButton.setTitleColor(curTab == .playmate ? selectedColor : normalColor, for: .normal)
  82. tabSelectionView.snp.remakeConstraints { make in
  83. make.centerY.equalToSuperview()
  84. make.leading.equalTo(selectedButton.snp.leading).offset(3)
  85. make.trailing.equalTo(selectedButton.snp.trailing).offset(-3)
  86. make.height.equalTo(26)
  87. }
  88. UIView.animate(withDuration: 0.25) { [weak self] in
  89. self?.tabBackgroundView.layoutIfNeeded()
  90. }
  91. }
  92. private func setupViews() {
  93. container.backgroundColor = .fill_7
  94. let tabView = buildTabView()
  95. container.addSubview(tabView)
  96. tabView.snp.makeConstraints { make in
  97. make.top.equalToSuperview().offset(16)
  98. make.horizontalEdges.equalToSuperview().inset(33)
  99. make.height.equalTo(32)
  100. }
  101. let countView = buildCountView()
  102. container.addSubview(countView)
  103. countView.snp.makeConstraints { make in
  104. make.top.equalTo(tabView.snp.bottom).offset(16)
  105. make.horizontalEdges.equalToSuperview().inset(16)
  106. make.height.equalTo(30)
  107. }
  108. let clearButton = UIButton()
  109. clearButton.layer.cornerRadius = 23.5
  110. clearButton.layer.borderColor = .fill_7
  111. clearButton.layer.borderWidth = 1
  112. clearButton.setTitle(.init(key: "A00335"), for: .normal)
  113. clearButton.setTitleColor(.text_2, for: .normal)
  114. clearButton.titleLabel?.font = .heading_h3
  115. clearButton.addAction(UIAction(handler: { [weak self] _ in
  116. guard let self else { return }
  117. }), for: .touchUpInside)
  118. container.addSubview(clearButton)
  119. clearButton.snp.makeConstraints { make in
  120. make.horizontalEdges.equalToSuperview().inset(16)
  121. make.bottom.equalToSuperview().offset(commonBottomInset)
  122. make.height.equalTo(47)
  123. }
  124. tableView.backgroundColor = .clear
  125. tableView.separatorStyle = .none
  126. tableView.showsVerticalScrollIndicator = false
  127. tableView.showsHorizontalScrollIndicator = false
  128. tableView.rowHeight = 64
  129. tableView.dataSource = self
  130. tableView.delegate = self
  131. tableView.register(LNRoomSeatApplyListCell.self, forCellReuseIdentifier: LNRoomSeatApplyListCell.className)
  132. container.addSubview(tableView)
  133. tableView.snp.makeConstraints { make in
  134. make.top.equalTo(countView.snp.bottom).offset(8)
  135. make.horizontalEdges.equalToSuperview().inset(16)
  136. make.bottom.equalTo(clearButton.snp.top)
  137. }
  138. }
  139. private func buildTabView() -> UIView {
  140. tabBackgroundView.backgroundColor = .fill.withAlphaComponent(0.2)
  141. tabBackgroundView.layer.cornerRadius = 16
  142. tabBackgroundView.clipsToBounds = true
  143. tabSelectionView.backgroundColor = .primary_1
  144. tabSelectionView.layer.cornerRadius = 13
  145. tabSelectionView.isUserInteractionEnabled = false
  146. tabBackgroundView.addSubview(tabSelectionView)
  147. let stackView = UIStackView()
  148. stackView.axis = .horizontal
  149. stackView.distribution = .fillEqually
  150. tabBackgroundView.addSubview(stackView)
  151. stackView.snp.makeConstraints { make in
  152. make.edges.equalToSuperview()
  153. }
  154. guestTabButton.setTitle(.init(key: "A00331"), for: .normal)
  155. guestTabButton.titleLabel?.font = .heading_h4
  156. guestTabButton.addAction(UIAction(handler: { [weak self] _ in
  157. self?.curTab = .guest
  158. }), for: .touchUpInside)
  159. stackView.addArrangedSubview(guestTabButton)
  160. playmateTabButton.setTitle(.init(key: "A00332"), for: .normal)
  161. playmateTabButton.titleLabel?.font = .heading_h4
  162. playmateTabButton.addAction(UIAction(handler: { [weak self] _ in
  163. self?.curTab = .playmate
  164. }), for: .touchUpInside)
  165. stackView.addArrangedSubview(playmateTabButton)
  166. return tabBackgroundView
  167. }
  168. private func buildCountView() -> UIView {
  169. let container = UIView()
  170. let stackView = UIStackView()
  171. stackView.axis = .horizontal
  172. stackView.spacing = 5
  173. stackView.alignment = .center
  174. container.addSubview(stackView)
  175. stackView.snp.makeConstraints { make in
  176. make.leading.centerY.equalToSuperview()
  177. }
  178. countLabel.font = .body_m
  179. countLabel.textColor = .text_6
  180. stackView.addArrangedSubview(countLabel)
  181. countDescLabel.font = .body_m
  182. countDescLabel.textColor = .text_1
  183. countDescLabel.text = .init(key: "A00333")
  184. stackView.addArrangedSubview(countDescLabel)
  185. filterButton.backgroundColor = .fill.withAlphaComponent(0.15)
  186. filterButton.layer.cornerRadius = 15
  187. filterButton.clipsToBounds = true
  188. filterButton.titleLabel?.font = .body_s
  189. filterButton.setTitleColor(.text_1, for: .normal)
  190. filterButton.setImage(.init(systemName: "chevron.down"), for: .normal)
  191. filterButton.tintColor = .text_1
  192. filterButton.semanticContentAttribute = .forceRightToLeft
  193. filterButton.imageEdgeInsets = .init(top: 0, left: 4, bottom: 0, right: -4)
  194. filterButton.contentEdgeInsets = .init(top: 0, left: 12, bottom: 0, right: 12)
  195. filterButton.addAction(UIAction(handler: { [weak self] _ in
  196. guard let self else { return }
  197. }), for: .touchUpInside)
  198. container.addSubview(filterButton)
  199. filterButton.snp.makeConstraints { make in
  200. make.centerY.trailing.equalToSuperview()
  201. make.height.equalTo(30)
  202. }
  203. return container
  204. }
  205. }