ThimraTV/MoviaBox/Class/Home/View/SPHomeCategoryVideoView.swift

258 lines
8.0 KiB
Swift

//
// SPHomeCategoryVideoView.swift
// MoviaBox
//
// Created by on 2025/5/15.
//
import UIKit
class SPHomeCategoryVideoView: UIView {
static func contentHeight() -> CGFloat {
return 372
}
override var intrinsicContentSize: CGSize {
let width = kSPScreenWidth
return CGSize(width: width, height: Self.contentHeight())
}
var image: UIImage? {
didSet {
bgImageView.image = image
}
}
var dataArr: [SPShortModel] = [] {
didSet {
if dataArr.count > 10 {
topDataArr = Array(dataArr.prefix(10))
bottomDataArr = Array(dataArr.suffix(from: dataArr.count - 10))
} else {
topDataArr = dataArr
bottomDataArr.removeAll()
}
self.topCollectionView.reloadData()
updateTimerState()
}
}
var isDidAppear: Bool = false {
didSet {
updateTimerState()
}
}
private lazy var topDataArr: [SPShortModel] = []
private lazy var bottomDataArr: [SPShortModel] = []
private var timer: Timer?
private var displayLink: CADisplayLink?
///View
private var draggingView: UIScrollView?
//MARK: UI
private lazy var bgImageView: UIImageView = {
let imageView = UIImageView()
imageView.isUserInteractionEnabled = true
return imageView
}()
private lazy var collectionViewLayout: UICollectionViewFlowLayout = {
let layout = UICollectionViewFlowLayout()
layout.itemSize = CGSize(width: 101, height: 135)
layout.footerReferenceSize = CGSize(width: 8, height: 135)
layout.scrollDirection = .horizontal
layout.minimumLineSpacing = 8
return layout
}()
private lazy var topCollectionView: SPCollectionView = {
let collectionView = SPCollectionView(frame: .zero, collectionViewLayout: collectionViewLayout)
collectionView.delegate = self
collectionView.dataSource = self
collectionView.showsHorizontalScrollIndicator = false
SPHomeCategoryVideoCell.registerCell(collectionView: collectionView)
return collectionView
}()
private lazy var bottomCollectionView: SPCollectionView = {
let collectionView = SPCollectionView(frame: .zero, collectionViewLayout: collectionViewLayout)
collectionView.delegate = self
collectionView.dataSource = self
collectionView.showsHorizontalScrollIndicator = false
SPHomeCategoryVideoCell.registerCell(collectionView: collectionView)
return collectionView
}()
deinit {
self.displayLink?.invalidate()
self.timer?.invalidate()
}
override init(frame: CGRect) {
super.init(frame: frame)
_setupUI()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func updateTimerState() {
if dataArr.count > 0, isDidAppear {
startTimer()
} else {
stopTimer()
}
}
}
extension SPHomeCategoryVideoView {
private func startTimer() {
// if timer == nil {
// self.timer = Timer.scheduledTimer(timeInterval: 1, target: YYWeakProxy(target: self), selector: #selector(handleTimer), userInfo: nil, repeats: true)
// RunLoop.main.add(self.timer!, forMode: .common)
// }
if displayLink == nil {
displayLink = CADisplayLink(target: YYWeakProxy(target: self), selector: #selector(handleTimer))
displayLink?.add(to: .main, forMode: .common)
}
}
private func stopTimer() {
timer?.invalidate()
timer = nil
displayLink?.invalidate()
displayLink = nil
}
@objc private func handleTimer() {
// Top
if draggingView != topCollectionView {
let topOffset = CGPoint(x: topCollectionView.contentOffset.x + 0.5, y: 0)
if topOffset.x < topCollectionView.contentSize.width - topCollectionView.bounds.width {
topCollectionView.contentOffset = topOffset
} else {
topCollectionView.contentOffset = .zero
}
}
// Bottom
if draggingView != bottomCollectionView {
let bottomOffset = CGPoint(x: bottomCollectionView.contentOffset.x - 0.5, y: 0)
if bottomOffset.x > 0 {
bottomCollectionView.contentOffset = bottomOffset
} else {
bottomCollectionView.contentOffset = CGPoint(x: bottomCollectionView.contentSize.width - bottomCollectionView.bounds.width, y: 0)
}
}
}
}
extension SPHomeCategoryVideoView {
private func _setupUI() {
addSubview(bgImageView)
bgImageView.addSubview(topCollectionView)
bgImageView.addSubview(bottomCollectionView)
bgImageView.snp.makeConstraints { make in
make.left.equalToSuperview().offset(16)
make.right.equalToSuperview().offset(-16)
make.top.bottom.equalToSuperview()
}
topCollectionView.snp.makeConstraints { make in
make.left.right.equalToSuperview()
make.top.equalToSuperview().offset(70)
make.height.equalTo(self.collectionViewLayout.itemSize.height)
}
bottomCollectionView.snp.makeConstraints { make in
make.left.right.height.equalTo(topCollectionView)
make.top.equalTo(topCollectionView.snp.bottom).offset(8)
}
}
}
//MARK: -------------- UICollectionViewDelegate & UICollectionViewDataSource --------------
extension SPHomeCategoryVideoView: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let model: SPShortModel
if collectionView == topCollectionView {
model = topDataArr[indexPath.row]
} else {
model = bottomDataArr[indexPath.row]
}
let cell = SPHomeCategoryVideoCell.dequeueReusableCell(collectionView: collectionView, indexPath: indexPath)
cell.model = model
return cell
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if collectionView == topCollectionView {
return topDataArr.count
} else {
return bottomDataArr.count
}
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 3
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let model: SPShortModel
if collectionView == topCollectionView {
model = topDataArr[indexPath.row]
} else {
model = bottomDataArr[indexPath.row]
}
let vc = SPPlayerDetailViewController()
vc.shortPlayId = model.short_play_id
self.viewController?.navigationController?.pushViewController(vc, animated: true)
}
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
draggingView = scrollView
}
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
draggingView = nil
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let offsetX = scrollView.contentOffset.x
let contentWidth = scrollView.contentSize.width
let sectionWidth = contentWidth / 3
if contentWidth <= scrollView.size.width { return }
if offsetX < sectionWidth {
scrollView.contentOffset = CGPoint(x: sectionWidth * 2, y: 0)
} else if offsetX > sectionWidth * 2 {
scrollView.contentOffset = CGPoint(x: sectionWidth, y: 0)
}
}
}