MoviaBox/Thimra/Class/Player/View/SPEpisodeView.swift
2025-04-23 11:33:46 +08:00

317 lines
9.6 KiB
Swift

//
// SPEpisodeView.swift
// Thimra
//
// Created by on 2025/4/16.
//
import UIKit
class SPEpisodeView: HWPanModalContentView {
var currentIndex: Int = 0 {
didSet {
self.collectionView.reloadData()
}
}
var shortModel: SPShortModel? {
didSet {
coverImageView.sp_setImage(url: shortModel?.image_url)
titleLabel.text = shortModel?.name
desLabel.text = shortModel?.sp_description
}
}
var dataArr: [SPVideoInfoModel] = [] {
didSet {
self.collectionView.reloadData()
var menuDataArr = [String]()
let totalEpisode = dataArr.count
var index = 0
var remainingEpisodes = totalEpisode
while remainingEpisodes > 0 {
let minIndex = index * 30
var maxIndex = minIndex + 29
if maxIndex >= dataArr.count {
maxIndex = dataArr.count - 1
}
let minEpisode = dataArr[minIndex].episode ?? "0"
let maxEpisode = dataArr[maxIndex].episode ?? "0"
if minEpisode == maxEpisode {
menuDataArr.append("\(minEpisode)")
} else {
menuDataArr.append("\(minEpisode)-\(maxEpisode)")
}
remainingEpisodes -= 30
index += 1
}
self.menuView.dataArr = menuDataArr
}
}
var didSelectedIndex: ((_ index: Int) -> Void)?
var isDecelerating = false
var isDragging = false
//MARK: UI
private lazy var bgView: UIView = {
let view = UIImageView(image: UIImage(named: "episode_bg_image_01"))
return view
}()
private lazy var collectionViewLayout: UICollectionViewFlowLayout = {
let itemWidth = floor((kSPScreenWidth - 7 * 4 - 32) / 5)
let layout = UICollectionViewFlowLayout()
layout.itemSize = .init(width: itemWidth, height: 54)
layout.minimumLineSpacing = 7
layout.minimumInteritemSpacing = 7
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
SPEpisodeCell.registerCell(collectionView: collectionView)
return collectionView
}()
private lazy var indicatorView: UIView = {
let view = UIView()
view.backgroundColor = .color5A5C67()
view.layer.cornerRadius = 2.5
view.layer.masksToBounds = true
return view
}()
private lazy var coverImageView: SPImageView = {
let imageView = SPImageView()
imageView.layer.cornerRadius = 4
imageView.layer.masksToBounds = true
imageView.layer.borderColor = UIColor.colorFFFFFF(alpha: 0.26).cgColor
imageView.layer.borderWidth = 1
return imageView
}()
private lazy var titleLabel: UILabel = {
let label = UILabel()
label.font = .fontBold(ofSize: 14)
label.textColor = .colorFFFFFF()
label.numberOfLines = 2
return label
}()
private lazy var desLabel: UILabel = {
let label = UILabel()
label.font = .fontRegular(ofSize: 10)
label.textColor = .colorA8A5AA()
label.numberOfLines = 5
return label
}()
private lazy var lineView: UIView = {
let view = UIView()
view.backgroundColor = .color545454()
return view
}()
private lazy var menuView: SPEpisodeMenuView = {
let view = SPEpisodeMenuView()
view.didSelectedIndex = { [weak self] index in
guard let self = self else { return }
var row = 0
if index > 0 {
row = index * 30 + 10
let count = self.dataArr.count
if row >= count {
row = count - 1
}
}
let indexPath = IndexPath.init(row: row, section: 0)
self.collectionView.scrollToItem(at: indexPath, at: .centeredVertically, animated: true)
}
return view
}()
override init(frame: CGRect) {
super.init(frame: frame)
_setupUI()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
//MARK: HWPanModalPresentable
override func panScrollable() -> UIScrollView? {
return collectionView
}
override func longFormHeight() -> PanModalHeight {
return PanModalHeightMake(.content, kSPScreenHeight * (2 / 3))
}
override func showDragIndicator() -> Bool {
return false
}
override func backgroundConfig() -> HWBackgroundConfig {
let config = HWBackgroundConfig()
config.backgroundAlpha = 0.6
return config
}
// override func present(in view: UIView?) {
// super.present(in: view)
// self.hw_contentView.addEffectView(style: .dark)
// }
}
extension SPEpisodeView {
private func _setupUI() {
addSubview(bgView)
addSubview(indicatorView)
addSubview(coverImageView)
addSubview(titleLabel)
addSubview(desLabel)
addSubview(menuView)
addSubview(lineView)
addSubview(collectionView)
bgView.snp.makeConstraints { make in
make.edges.equalToSuperview()
}
self.indicatorView.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.top.equalToSuperview().offset(10)
make.width.equalTo(40)
make.height.equalTo(5)
}
self.coverImageView.snp.makeConstraints { make in
make.left.equalToSuperview().offset(15)
make.top.equalToSuperview().offset(39)
make.width.equalTo(70)
make.height.equalTo(104)
}
self.titleLabel.snp.makeConstraints { make in
make.left.equalTo(self.coverImageView.snp.right).offset(12)
make.right.lessThanOrEqualToSuperview().offset(-16)
make.top.equalTo(self.coverImageView)
}
self.desLabel.snp.makeConstraints { make in
make.left.equalTo(self.titleLabel)
make.right.lessThanOrEqualToSuperview().offset(-16)
// make.top.equalTo(self.coverImageView.snp.bottom).offset(8)
make.top.equalTo(titleLabel.snp.bottom).offset(6)
}
self.menuView.snp.makeConstraints { make in
make.left.right.equalTo(self.lineView)
make.bottom.equalTo(self.lineView)
}
self.lineView.snp.makeConstraints { make in
make.left.equalToSuperview().offset(16)
make.centerX.equalToSuperview()
make.top.equalTo(self.coverImageView.snp.bottom).offset(46)
make.height.equalTo(0.7)
}
self.collectionView.snp.makeConstraints { make in
// make.edges.equalToSuperview()
make.left.right.bottom.equalToSuperview()
make.top.equalTo(self.lineView.snp.bottom).offset(15)
}
}
}
//MARK: -------------- UICollectionViewDelegate & UICollectionViewDataSource --------------
extension SPEpisodeView: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = SPEpisodeCell.dequeueReusableCell(collectionView: collectionView, indexPath: indexPath)
cell.videoInfoModel = self.dataArr[indexPath.row]
cell.sp_isSelected = indexPath.row == currentIndex
return cell
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return self.dataArr.count
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
guard indexPath.row != currentIndex else { return }
self.didSelectedIndex?(indexPath.row)
self.dismiss(animated: true) {
}
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if isDragging || isDecelerating {
updateMuneSelectedIndex()
}
}
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
isDecelerating = false
updateMuneSelectedIndex()
}
func scrollViewWillBeginDecelerating(_ scrollView: UIScrollView) {
isDecelerating = true
}
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
isDragging = true
}
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
isDragging = false
}
func updateMuneSelectedIndex() {
let indexPathArr = collectionView.indexPathsForVisibleItems
var minRow = dataArr.count - 1
var maxRow = 0
for indexPath in indexPathArr {
if indexPath.row < minRow {
minRow = indexPath.row
}
if indexPath.row > maxRow {
maxRow = indexPath.row
}
}
let selectedIndex = maxRow / 30
if menuView.selectedIndex != selectedIndex {
menuView.selectedIndex = selectedIndex
}
}
}