| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- //
- // LNHomeGameTabView.swift
- // Lanu
- //
- // Created by OneeChan on 2025/11/14.
- //
- import Foundation
- import UIKit
- import SnapKit
- protocol LNHomeGameTabViewDelegate: AnyObject {
- func homeGameTabView(view: LNHomeGameTabView, didSelect category: LNGameCategoryItemVO?)
- func homeGameTabViewClickMore(view: LNHomeGameTabView)
- }
- class LNHomeGameTabView: UIView {
- private(set) var curGame: LNGameCategoryItemVO? {
- didSet {
- guard oldValue?.code != curGame?.code else { return }
- tabItemViews.forEach {
- $0.setSelected(curGame?.code == $0.item?.code)
- }
- delegate?.homeGameTabView(view: self, didSelect: curGame)
- }
- }
-
- private let indicator = UIImageView()
- private let stackView = UIStackView()
- private var tabItemViews: [LNHomeGameTabItemView] = []
-
- weak var delegate: LNHomeGameTabViewDelegate?
-
- override init(frame: CGRect) {
- super.init(frame: frame)
-
- setupViews()
- }
-
- func update(_ games: [LNGameCategoryItemVO]) {
- let itemViews = stackView.arrangedSubviews
- itemViews.forEach {
- stackView.removeArrangedSubview($0)
- $0.removeFromSuperview()
- }
- tabItemViews.removeAll()
-
- games.prefix(3).forEach { item in
- let itemView = LNHomeGameTabItemView()
- itemView.onTap { [weak self, weak itemView] in
- guard let self, let itemView else { return }
- let animated = self.curGame != nil
- if self.curGame?.code == item.code {
- self.curGame = nil
- self.indicator.isHidden = true
- } else {
- self.curGame = item
- self.indicator.isHidden = false
- }
- handleSelectAt(itemView, animated: animated)
- }
- itemView.update(item)
- stackView.addArrangedSubview(itemView)
- tabItemViews.append(itemView)
- }
- }
-
- required init?(coder: NSCoder) {
- fatalError("init(coder:) has not been implemented")
- }
- }
- extension LNHomeGameTabView {
- private func handleSelectAt(_ itemView: LNHomeGameTabItemView, animated: Bool = true) {
- indicator.snp.remakeConstraints { make in
- make.horizontalEdges.equalTo(itemView)
- make.bottom.equalToSuperview()
- }
- if animated {
- UIView.animate(withDuration: 0.25) { [weak self] in
- guard let self else { return }
- self.layoutIfNeeded()
- }
- }
- }
-
- private func setupViews() {
- indicator.image = .icHomeGameTabSelected
- addSubview(indicator)
-
- let moreView = LNHomeGameTabItemView()
- moreView.toBeMoreTab()
- moreView.onTap { [weak self] in
- guard let self else { return }
- self.delegate?.homeGameTabViewClickMore(view: self)
- }
- addSubview(moreView)
- moreView.snp.makeConstraints { make in
- make.top.equalToSuperview()
- make.trailing.equalToSuperview()
- }
-
- stackView.axis = .horizontal
- stackView.distribution = .fillEqually
- addSubview(stackView)
- stackView.snp.makeConstraints { make in
- make.leading.equalToSuperview()
- make.top.equalToSuperview()
- make.trailing.equalTo(moreView.snp.leading).offset(-20)
- }
- }
- }
- #if DEBUG
- import SwiftUI
- struct LNHomeGameTabViewPreview: UIViewRepresentable {
- func makeUIView(context: Context) -> some UIView {
- let container = UIView()
- container.backgroundColor = .lightGray
-
- let view = LNHomeGameTabView()
- container.addSubview(view)
- view.snp.makeConstraints { make in
- make.leading.trailing.top.equalToSuperview()
- }
-
- return container
- }
-
- func updateUIView(_ uiView: UIViewType, context: Context) { }
- }
- #Preview(body: {
- LNHomeGameTabViewPreview()
- })
- #endif
|