// // SPAllShortViewController.swift // Thimra // // Created by Overseas on 2025/4/23. // import UIKit class SPAllShortViewController: SPViewController { private lazy var allCategoryModel: SPCategoryModel = { let model = SPCategoryModel() model.id = "0" model.name = "All".localized return model }() private lazy var categoryArr: [SPCategoryModel] = [self.allCategoryModel] private lazy var currentCategoryModel: SPCategoryModel = self.allCategoryModel private lazy var dataArr: [SPShortModel] = [] private lazy var page = 1 private lazy var isOpen = false private var tagMaxHeight: CGFloat { var height = CGFloat(MAXFLOAT) if !isOpen { height = tagView.tagHeight * 2 + tagView.tagVerticalGap } return height } //MARK: UI属性 private lazy var tagView: JXTagView = { let tagView = JXTagView() tagView.delegate = self tagView.dataSource = self tagView.tagHeight = 24 tagView.tagCornerRadius = 12 tagView.tagBorderWidth = 1 tagView.tagBorderColor = .clear tagView.tagBorderSelectedColor = .colorFF4B5A() tagView.textColor = .colorCCCCCC() tagView.textSelectedColor = .colorFF4B5A() tagView.tagBackgroundColor = .clear tagView.tagSelectedBackgroundColor = .clear tagView.textFont = .fontRegular(ofSize: 14) tagView.textMargin = 14 tagView.tagVerticalGap = 5 tagView.tagHorizontalGap = 0 tagView.leftAndRightMargin = 16 return tagView }() ///展开按钮边上的渐变 private lazy var openGradientLayer: CAGradientLayer = { let layer = CAGradientLayer() layer.colors = [UIColor.clear.withAlphaComponent(1).cgColor, UIColor.clear.withAlphaComponent(0).cgColor] layer.locations = [0, 1] layer.rasterizationScale = UIScreen.main.scale layer.startPoint = CGPoint(x: 0.7, y: 0.5) layer.endPoint = CGPoint(x: 1, y: 1) // layer.frame = CGRect(x: 0, y: 0, width: 100, height: tagView.height) return layer }() private lazy var openButton: UIButton = { let button = UIButton(type: .custom) button.setImage(UIImage(named: "arrow_bown_icon_01"), for: .normal) button.setImage(UIImage(named: "arrow_up_icon_01"), for: .selected) button.setImage(UIImage(named: "arrow_up_icon_01"), for: [.selected, .highlighted]) button.addTarget(self, action: #selector(handleOpenButton), for: .touchUpInside) return button }() private lazy var bgView: UIView = { let view = UIView() view.addEffectView(style: .dark) return view }() private lazy var collectionViewLayout: UICollectionViewFlowLayout = { let width = floor((kSPScreenWidth - 32 - 14 * 2) / 3) let height = 145 / 105 * width + 36 let layout = UICollectionViewFlowLayout() layout.itemSize = CGSize(width: width, height: height) layout.minimumLineSpacing = 14 layout.minimumInteritemSpacing = 14 layout.sectionInset = .init(top: 0, left: 16, bottom: 0, right: 16) return layout }() private lazy var collectionView: SPCollectionView = { let collectionView = SPCollectionView(frame: .zero, collectionViewLayout: collectionViewLayout) collectionView.delegate = self collectionView.dataSource = self collectionView.contentInset = .init(top: 10, left: 0, bottom: 10, right: 0) collectionView.sp_addRefreshHeader(insetTop: collectionView.contentInset.top) { [weak self] in self?.handleHeaderRefresh(nil) } collectionView.sp_addRefreshBackFooter(insetBottom: collectionView.contentInset.bottom) { [weak self] in self?.handleFooterRefresh(nil) } SPAllShortCell.registerCell(collectionView: collectionView) return collectionView }() override func viewDidLoad() { super.viewDidLoad() self.view.backgroundColor = .clear requestCategoryList() requestDataArr(page: 1, completer: nil) _setupUI() } override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() let widht: CGFloat = 100 let height = self.tagView.tagHeight let x = self.tagView.width - widht let y = self.tagView.height - height // openGradientLayer.frame = CGRect(x: x, y: y, width: widht, height: height) openGradientLayer.frame = self.tagView.bounds } override func setBgImageView() { } override func handleHeaderRefresh(_ completer: (() -> Void)?) { requestDataArr(page: 1) { [weak self] in self?.collectionView.sp_endHeaderRefreshing() } } override func handleFooterRefresh(_ completer: (() -> Void)?) { requestDataArr(page: self.page + 1) { [weak self] in self?.collectionView.sp_endFooterRefreshing() } } @objc private func handleOpenButton() { self.isOpen = !self.isOpen self.openButton.isSelected = self.isOpen tagView.snp.updateConstraints { make in make.height.lessThanOrEqualTo(tagMaxHeight) } } } extension SPAllShortViewController { private func _setupUI() { tagView.layer.mask = self.openGradientLayer view.addSubview(tagView) view.addSubview(bgView) view.addSubview(openButton) bgView.addSubview(collectionView) tagView.snp.makeConstraints { make in make.left.right.equalToSuperview() make.top.equalToSuperview().offset(kSPStatusbarHeight + 40 + 12) make.height.lessThanOrEqualTo(tagMaxHeight) } openButton.snp.makeConstraints { make in make.right.equalToSuperview().offset(-16) make.bottom.equalTo(tagView) make.height.equalTo(tagView.tagHeight) } bgView.snp.makeConstraints { make in make.left.right.bottom.equalToSuperview() make.top.equalTo(tagView.snp.bottom).offset(5) } collectionView.snp.makeConstraints { make in make.left.right.bottom.equalToSuperview() make.top.equalToSuperview() } } } //MARK: -------------- UICollectionViewDelegate & UICollectionViewDataSource -------------- extension SPAllShortViewController: UICollectionViewDelegate, UICollectionViewDataSource { func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = SPAllShortCell.dequeueReusableCell(collectionView: collectionView, indexPath: indexPath) cell.model = dataArr[indexPath.row] return cell } func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return self.dataArr.count } func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { let model = dataArr[indexPath.row] let vc = SPPlayerDetailViewController() vc.shortPlayId = model.short_play_id self.navigationController?.pushViewController(vc, animated: true) } } //MARK: -------------- JXTagViewDelegate & JXTagViewDataSource -------------- extension SPAllShortViewController: JXTagViewDelegate, JXTagViewDataSource { func jx_number(in tagView: JXTagView) -> Int { return self.categoryArr.count } func jx_tagView(tagView: JXTagView, titleForIndex index: Int) -> String? { return self.categoryArr[index].name } func jx_tagView(tagView: JXTagView, selectedForIndex index: Int) -> Bool { let model = self.categoryArr[index] return model.id == self.currentCategoryModel.id } func jx_tagView(tagView: JXTagView, didSelectedTagAt index: Int) { let model = self.categoryArr[index] if model.id == self.currentCategoryModel.id { return } self.currentCategoryModel = model tagView.updateState() requestDataArr(page: 1, completer: nil) } } extension SPAllShortViewController { private func requestCategoryList() { SPVideoAPI.requestShortCategoryList { [weak self] list in guard let self = self else { return } if let list = list { self.categoryArr = list self.categoryArr.insert(self.allCategoryModel, at: 0) self.tagView.reloadData() } } } private func requestDataArr(page: Int, completer: (() -> Void)?) { guard let id = self.currentCategoryModel.id else { return } SPVideoAPI.requestCategoryShortList(page: page, id: id) { [weak self] listModel in guard let self = self else { return } if let list = listModel?.list { if page == 1 { self.dataArr.removeAll() } self.dataArr += list self.page = page self.collectionView.reloadData() } completer?() } } }