// // LNJoinUsSelectSkillView.swift // Gami // // Created by OneeChan on 2026/1/19. // import Foundation import UIKit import SnapKit protocol LNJoinUsSelectSkillViewDelegate: AnyObject { func joinUsSelectSkillView(view: LNJoinUsSelectSkillView, didSelect skill: LNGameCategoryItemVO) } class LNJoinUsSelectSkillView: UIView { private let columns = 4 private let collectionViewLayout = UICollectionViewFlowLayout() private let collectionView: UICollectionView private var categories: [LNGameTypeItemVO] = [] weak var delegate: LNJoinUsSelectSkillViewDelegate? override init(frame: CGRect) { collectionView = UICollectionView(frame: .zero, collectionViewLayout: collectionViewLayout) super.init(frame: frame) setupViews() update(categories: LNGameMateManager.shared.curGameTypes) } private func update(categories: [LNGameTypeItemVO]) { self.categories = categories collectionView.reloadData() } override func layoutSubviews() { super.layoutSubviews() let width = (collectionView.bounds.width - collectionViewLayout.minimumInteritemSpacing) / CGFloat(columns) - collectionViewLayout.minimumInteritemSpacing collectionViewLayout.itemSize = .init(width: width, height: 68) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } } extension LNJoinUsSelectSkillView: UICollectionViewDataSource, UICollectionViewDelegate { func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { categories[section].children.count } func numberOfSections(in collectionView: UICollectionView) -> Int { categories.count } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: LNJoinUsSelectSkillCell.className, for: indexPath) as! LNJoinUsSelectSkillCell let item = categories[indexPath.section].children[indexPath.row] cell.tabItemView.update(item) return cell } func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { guard kind == UICollectionView.elementKindSectionHeader else { return UICollectionReusableView() } let view = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: LNJoinUsSelectSkillHeader.className, for: indexPath) as! LNJoinUsSelectSkillHeader let section = categories[indexPath.section] view.update(section.name) return view } func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { let category = categories[indexPath.section] let game = category.children[indexPath.row] delegate?.joinUsSelectSkillView(view: self, didSelect: game) } } extension LNJoinUsSelectSkillView { private func setupViews() { collectionViewLayout.itemSize = .init(width: 77, height: 68) collectionViewLayout.minimumLineSpacing = 10 collectionViewLayout.minimumInteritemSpacing = 12 collectionViewLayout.headerReferenceSize = .init(width: 100, height: LNJoinUsSelectSkillHeader.height) collectionViewLayout.sectionInset = .init(top: 0, left: 12, bottom: 40, right: 12) collectionView.backgroundColor = .clear collectionView.dataSource = self collectionView.delegate = self collectionView.contentInsetAdjustmentBehavior = .never collectionView.showsHorizontalScrollIndicator = false collectionView.showsVerticalScrollIndicator = false collectionView.register(LNJoinUsSelectSkillCell.self, forCellWithReuseIdentifier: LNJoinUsSelectSkillCell.className) collectionView.register(LNJoinUsSelectSkillHeader.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: LNJoinUsSelectSkillHeader.className) addSubview(collectionView) collectionView.snp.makeConstraints { make in make.horizontalEdges.equalToSuperview().inset(6) make.top.equalToSuperview().offset(17) make.bottom.equalToSuperview() } } } private class LNJoinUsSelectSkillCell: UICollectionViewCell { let tabItemView = LNHomeGameTabItemView() override init(frame: CGRect) { super.init(frame: frame) contentView.addSubview(tabItemView) tabItemView.snp.makeConstraints { make in make.edges.equalToSuperview() } } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } } private class LNJoinUsSelectSkillHeader: UICollectionReusableView { static let height = 36 private let titleLabel = UILabel() override init(frame: CGRect) { super.init(frame: frame) snp.makeConstraints { make in make.height.equalTo(Self.height) } titleLabel.font = .heading_h2 titleLabel.textColor = .text_5 addSubview(titleLabel) titleLabel.snp.makeConstraints { make in make.bottom.equalToSuperview().offset(-8) make.leading.equalToSuperview().offset(10) } } func update(_ title: String) { titleLabel.text = title } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } }