LNJoinUsSelectSkillView.swift 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. //
  2. // LNJoinUsSelectSkillView.swift
  3. // Gami
  4. //
  5. // Created by OneeChan on 2026/1/19.
  6. //
  7. import Foundation
  8. import UIKit
  9. import SnapKit
  10. protocol LNJoinUsSelectSkillViewDelegate: AnyObject {
  11. func joinUsSelectSkillView(view: LNJoinUsSelectSkillView, didSelect skill: LNGameCategoryItemVO)
  12. }
  13. class LNJoinUsSelectSkillView: UIView {
  14. private let columns = 4
  15. private let collectionViewLayout = UICollectionViewFlowLayout()
  16. private let collectionView: UICollectionView
  17. private var categories: [LNGameTypeItemVO] = []
  18. weak var delegate: LNJoinUsSelectSkillViewDelegate?
  19. override init(frame: CGRect) {
  20. collectionView = UICollectionView(frame: .zero, collectionViewLayout: collectionViewLayout)
  21. super.init(frame: frame)
  22. setupViews()
  23. update(categories: LNGameMateManager.shared.curGameTypes)
  24. }
  25. private func update(categories: [LNGameTypeItemVO]) {
  26. self.categories = categories
  27. collectionView.reloadData()
  28. }
  29. override func layoutSubviews() {
  30. super.layoutSubviews()
  31. let width = (collectionView.bounds.width - collectionViewLayout.minimumInteritemSpacing) / CGFloat(columns) - collectionViewLayout.minimumInteritemSpacing
  32. collectionViewLayout.itemSize = .init(width: width, height: 68)
  33. }
  34. required init?(coder: NSCoder) {
  35. fatalError("init(coder:) has not been implemented")
  36. }
  37. }
  38. extension LNJoinUsSelectSkillView: UICollectionViewDataSource, UICollectionViewDelegate {
  39. func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
  40. categories[section].children.count
  41. }
  42. func numberOfSections(in collectionView: UICollectionView) -> Int {
  43. categories.count
  44. }
  45. func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
  46. let cell = collectionView.dequeueReusableCell(withReuseIdentifier: LNJoinUsSelectSkillCell.className, for: indexPath) as! LNJoinUsSelectSkillCell
  47. let item = categories[indexPath.section].children[indexPath.row]
  48. cell.tabItemView.update(item)
  49. return cell
  50. }
  51. func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
  52. guard kind == UICollectionView.elementKindSectionHeader else {
  53. return UICollectionReusableView()
  54. }
  55. let view = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: LNJoinUsSelectSkillHeader.className, for: indexPath) as! LNJoinUsSelectSkillHeader
  56. let section = categories[indexPath.section]
  57. view.update(section.name)
  58. return view
  59. }
  60. func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
  61. let category = categories[indexPath.section]
  62. let game = category.children[indexPath.row]
  63. delegate?.joinUsSelectSkillView(view: self, didSelect: game)
  64. }
  65. }
  66. extension LNJoinUsSelectSkillView {
  67. private func setupViews() {
  68. collectionViewLayout.itemSize = .init(width: 77, height: 68)
  69. collectionViewLayout.minimumLineSpacing = 10
  70. collectionViewLayout.minimumInteritemSpacing = 12
  71. collectionViewLayout.headerReferenceSize = .init(width: 100, height: LNJoinUsSelectSkillHeader.height)
  72. collectionViewLayout.sectionInset = .init(top: 0, left: 12, bottom: 40, right: 12)
  73. collectionView.backgroundColor = .clear
  74. collectionView.dataSource = self
  75. collectionView.delegate = self
  76. collectionView.contentInsetAdjustmentBehavior = .never
  77. collectionView.showsHorizontalScrollIndicator = false
  78. collectionView.showsVerticalScrollIndicator = false
  79. collectionView.register(LNJoinUsSelectSkillCell.self, forCellWithReuseIdentifier: LNJoinUsSelectSkillCell.className)
  80. collectionView.register(LNJoinUsSelectSkillHeader.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: LNJoinUsSelectSkillHeader.className)
  81. addSubview(collectionView)
  82. collectionView.snp.makeConstraints { make in
  83. make.horizontalEdges.equalToSuperview().inset(6)
  84. make.top.equalToSuperview().offset(17)
  85. make.bottom.equalToSuperview()
  86. }
  87. }
  88. }
  89. private class LNJoinUsSelectSkillCell: UICollectionViewCell {
  90. let tabItemView = LNHomeGameTabItemView()
  91. override init(frame: CGRect) {
  92. super.init(frame: frame)
  93. contentView.addSubview(tabItemView)
  94. tabItemView.snp.makeConstraints { make in
  95. make.edges.equalToSuperview()
  96. }
  97. }
  98. required init?(coder: NSCoder) {
  99. fatalError("init(coder:) has not been implemented")
  100. }
  101. }
  102. private class LNJoinUsSelectSkillHeader: UICollectionReusableView {
  103. static let height = 36
  104. private let titleLabel = UILabel()
  105. override init(frame: CGRect) {
  106. super.init(frame: frame)
  107. snp.makeConstraints { make in
  108. make.height.equalTo(Self.height)
  109. }
  110. titleLabel.font = .heading_h2
  111. titleLabel.textColor = .text_5
  112. addSubview(titleLabel)
  113. titleLabel.snp.makeConstraints { make in
  114. make.bottom.equalToSuperview().offset(-8)
  115. make.leading.equalToSuperview().offset(10)
  116. }
  117. }
  118. func update(_ title: String) {
  119. titleLabel.text = title
  120. }
  121. required init?(coder: NSCoder) {
  122. fatalError("init(coder:) has not been implemented")
  123. }
  124. }