LNEditInterestPanel.swift 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. //
  2. // LNEditInterestPanel.swift
  3. // Lanu
  4. //
  5. // Created by OneeChan on 2025/12/19.
  6. //
  7. import Foundation
  8. import UIKit
  9. import SnapKit
  10. class LNEditInterestPanel: LNPopupView {
  11. private var actegoryViews: [LNAutoFillStackView] = []
  12. private var curSelected: [LNGameCategoryItemVO] = []
  13. private let confirmButton = UIButton()
  14. private let maxCount = LNGameMateManager.gameSelectionMaxCount
  15. private var allInterests: [LNInterestItemView] = []
  16. var handler: (([LNGameCategoryItemVO]) -> Void)?
  17. init(selecteds: [String]) {
  18. super.init(frame: .zero)
  19. curSelected = selecteds.compactMap({
  20. LNGameMateManager.shared.gameCategory(for: $0)
  21. })
  22. setupViews()
  23. updateConfirmButton()
  24. }
  25. required init?(coder: NSCoder) {
  26. fatalError("init(coder:) has not been implemented")
  27. }
  28. }
  29. extension LNEditInterestPanel {
  30. private func updateConfirmButton() {
  31. if curSelected.isEmpty, confirmButton.isEnabled {
  32. confirmButton.isEnabled = false
  33. confirmButton.setBackgroundImage(nil, for: .normal)
  34. } else if !curSelected.isEmpty, !confirmButton.isEnabled {
  35. confirmButton.isEnabled = true
  36. confirmButton.setBackgroundImage(.primary_8, for: .normal)
  37. }
  38. }
  39. private func updateList() {
  40. allInterests.forEach { itemView in
  41. itemView.isSelected = curSelected.contains(where: { $0.code == itemView.curItem?.code })
  42. itemView.isEnable = itemView.isSelected || curSelected.count < LNGameMateManager.gameSelectionMaxCount
  43. }
  44. }
  45. private func setupViews() {
  46. container.clipsToBounds = true
  47. let background = UIImageView()
  48. background.image = .icLoginInterestBg
  49. container.addSubview(background)
  50. background.snp.makeConstraints { make in
  51. make.horizontalEdges.equalToSuperview()
  52. make.top.equalToSuperview()
  53. }
  54. let titleLabel = UILabel()
  55. titleLabel.font = .heading_h3
  56. titleLabel.textColor = .text_5
  57. titleLabel.text = .init(key: "A00186")
  58. container.addSubview(titleLabel)
  59. titleLabel.snp.makeConstraints { make in
  60. make.centerX.equalToSuperview()
  61. make.top.equalToSuperview().offset(16)
  62. }
  63. let descLabel = UILabel()
  64. descLabel.text = .init(key: "A00187")
  65. descLabel.font = .body_s
  66. descLabel.textColor = .text_4
  67. descLabel.textAlignment = .center
  68. container.addSubview(descLabel)
  69. descLabel.snp.makeConstraints { make in
  70. make.horizontalEdges.equalToSuperview().inset(16)
  71. make.top.equalTo(titleLabel.snp.bottom).offset(6)
  72. }
  73. let holder = UIView()
  74. holder.backgroundColor = .fill
  75. holder.layer.cornerRadius = 20
  76. container.addSubview(holder)
  77. holder.snp.makeConstraints { make in
  78. make.horizontalEdges.equalToSuperview().inset(16)
  79. make.top.equalTo(descLabel.snp.bottom).offset(12)
  80. }
  81. let stackView = UIStackView()
  82. stackView.axis = .vertical
  83. stackView.spacing = 12
  84. holder.addSubview(stackView)
  85. stackView.snp.makeConstraints { make in
  86. make.edges.equalToSuperview().inset(14)
  87. }
  88. buildCategoryViews().forEach {
  89. stackView.addArrangedSubview($0)
  90. }
  91. confirmButton.setTitle(.init(key: "A00185"), for: .normal)
  92. confirmButton.setTitleColor(.text_1, for: .normal)
  93. confirmButton.titleLabel?.font = .heading_h3
  94. confirmButton.setBackgroundImage(.primary_8, for: .normal)
  95. confirmButton.layer.cornerRadius = 23.5
  96. confirmButton.clipsToBounds = true
  97. confirmButton.backgroundColor = .fill_4
  98. confirmButton.addAction(UIAction(handler: { [weak self] _ in
  99. guard let self else { return }
  100. dismiss()
  101. handler?(curSelected)
  102. }), for: .touchUpInside)
  103. container.addSubview(confirmButton)
  104. confirmButton.snp.makeConstraints { make in
  105. make.horizontalEdges.equalToSuperview().inset(12)
  106. make.top.equalTo(holder.snp.bottom).offset(16)
  107. make.bottom.equalToSuperview().offset(commonBottomInset)
  108. make.height.equalTo(47)
  109. }
  110. }
  111. private func buildCategoryViews() -> [UIView] {
  112. var views: [UIView] = []
  113. for category in LNGameMateManager.shared.curGameTypes {
  114. let container = UIView()
  115. let titleLabel = UILabel()
  116. titleLabel.text = category.name
  117. titleLabel.font = .heading_h4
  118. titleLabel.textColor = .text_5
  119. container.addSubview(titleLabel)
  120. titleLabel.snp.makeConstraints { make in
  121. make.leading.equalToSuperview()
  122. make.top.equalToSuperview()
  123. }
  124. let multiLineView = LNAutoFillStackView()
  125. multiLineView.itemSpacing = 8
  126. multiLineView.spacing = 10
  127. container.addSubview(multiLineView)
  128. multiLineView.snp.makeConstraints { make in
  129. make.horizontalEdges.equalToSuperview()
  130. make.bottom.equalToSuperview()
  131. make.top.equalTo(titleLabel.snp.bottom).offset(10)
  132. }
  133. var itemViews: [UIView] = []
  134. category.children.forEach { item in
  135. let itemView = LNInterestItemView()
  136. itemView.update(item)
  137. itemView.onTap { [weak self] in
  138. guard let self else { return }
  139. if curSelected.contains(where: { $0.code == item.code }) {
  140. curSelected.removeAll { $0.code == item.code }
  141. } else if curSelected.count < LNGameMateManager.gameSelectionMaxCount{
  142. curSelected.append(item)
  143. }
  144. updateList()
  145. updateConfirmButton()
  146. }
  147. allInterests.append(itemView)
  148. itemViews.append(itemView)
  149. }
  150. multiLineView.update(itemViews)
  151. views.append(container)
  152. }
  153. updateList()
  154. return views
  155. }
  156. }
  157. private class LNInterestItemView: UIView {
  158. private let titleLabel = UILabel()
  159. private(set) var curItem: LNGameCategoryItemVO?
  160. var isSelected: Bool = false {
  161. didSet {
  162. if isSelected {
  163. titleLabel.font = .heading_h5
  164. titleLabel.textColor = .text_6
  165. backgroundColor = .fill_5
  166. } else {
  167. titleLabel.font = .body_s
  168. titleLabel.textColor = .text_4
  169. backgroundColor = .fill_1
  170. }
  171. }
  172. }
  173. var isEnable: Bool = true {
  174. didSet {
  175. alpha = isEnable ? 1.0 : 0.5
  176. isUserInteractionEnabled = isEnable
  177. }
  178. }
  179. override init(frame: CGRect) {
  180. super.init(frame: frame)
  181. backgroundColor = .fill_1
  182. layer.cornerRadius = 12
  183. snp.makeConstraints { make in
  184. make.height.equalTo(24)
  185. }
  186. titleLabel.font = .body_s
  187. titleLabel.textColor = .text_4
  188. addSubview(titleLabel)
  189. titleLabel.snp.makeConstraints { make in
  190. make.center.equalToSuperview()
  191. make.horizontalEdges.equalToSuperview().inset(11)
  192. }
  193. }
  194. func update(_ item: LNGameCategoryItemVO) {
  195. titleLabel.text = item.name
  196. curItem = item
  197. }
  198. required init?(coder: NSCoder) {
  199. fatalError("init(coder:) has not been implemented")
  200. }
  201. }