| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- //
- // LNVideoPreviewController.swift
- // Gami
- //
- // Created by OneeChan on 2026/3/4.
- //
- import Foundation
- import UIKit
- import SnapKit
- extension UIView {
- func presentVideoPreview(_ urls: [String], _ targetIndex: Int) {
- let vc = LNVideoPreviewController()
- vc.loadVideos(urls: urls, targetIndex: targetIndex)
- vc.modalPresentationStyle = .overFullScreen
- viewController?.present(vc, animated: true)
- }
- }
- class LNVideoPreviewController: LNViewController {
- private var videoURLs: [String] = []
- private var curIndex: Int = 0 {
- didSet {
- titleLabel.text = "\(curIndex + 1)/\(videoURLs.count)"
- }
- }
-
- private var collectionView: UICollectionView?
-
- private let fakeBar = LNFakeNaviBar()
- private let titleLabel = UILabel()
-
- func loadVideos(urls: [String], targetIndex: Int) {
- videoURLs = urls
- curIndex = targetIndex
-
- collectionView?.reloadData()
- DispatchQueue.main.async { [weak self] in
- guard let self else { return }
- collectionView?.scrollToItem(
- at: .init(row: curIndex, section: 0),
- at: .centeredHorizontally,
- animated: false)
- }
- }
-
- override func viewDidLoad() {
- super.viewDidLoad()
-
- showNavigationBar = false
- setupViews()
- }
- }
- extension LNVideoPreviewController: LNVideoPreviewCellDelegate {
- func onVideoPreviewCellDragToDismiss(cell: LNVideoPreviewCell) {
- dismiss(animated: false)
- }
- }
- extension LNVideoPreviewController: UICollectionViewDataSource, UICollectionViewDelegate {
- func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
- videoURLs.count
- }
-
- func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
- let cell = collectionView.dequeueReusableCell(withReuseIdentifier: LNVideoPreviewCell.className, for: indexPath) as! LNVideoPreviewCell
- cell.update(url: videoURLs[indexPath.row], coverUrl: nil)
- cell.delegate = self
- return cell
- }
-
- func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
- let previewCell = cell as! LNVideoPreviewCell
- previewCell.stop()
- }
-
- func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
- curIndex = Int(scrollView.contentOffset.x / scrollView.bounds.width)
- }
-
- func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
- curIndex = Int(scrollView.contentOffset.x / scrollView.bounds.width)
- }
- }
- extension LNVideoPreviewController {
- private func setupViews() {
- view.backgroundColor = .clear
-
- let layout = UICollectionViewFlowLayout()
- layout.scrollDirection = .horizontal
- layout.itemSize = view.bounds.size
- layout.minimumLineSpacing = 0
- layout.minimumInteritemSpacing = 0
-
- let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
- collectionView.isPagingEnabled = true
- collectionView.showsHorizontalScrollIndicator = false
- collectionView.backgroundColor = .black
- collectionView.register(LNVideoPreviewCell.self, forCellWithReuseIdentifier: LNVideoPreviewCell.className)
- collectionView.dataSource = self
- collectionView.delegate = self
- view.addSubview(collectionView)
- collectionView.snp.makeConstraints { make in
- make.edges.equalToSuperview()
- }
- self.collectionView = collectionView
-
- let fakeBar = buildFakeNavBar()
- view.addSubview(fakeBar)
- fakeBar.snp.makeConstraints { make in
- make.horizontalEdges.equalToSuperview()
- make.top.equalToSuperview()
- }
- }
-
- private func buildFakeNavBar() -> UIView {
- fakeBar.showBackButton { [weak self] in
- guard let self else { return }
- dismiss(animated: true)
- }
- fakeBar.backButton?.setImage(.init(systemName: "chevron.backward")?.withRenderingMode(.alwaysTemplate), for: .normal)
- fakeBar.backButton?.tintColor = .fill
-
- titleLabel.font = .body_l
- titleLabel.textColor = .text_1
- fakeBar.actionView.addSubview(titleLabel)
- titleLabel.snp.makeConstraints { make in
- make.center.equalToSuperview()
- }
-
- return fakeBar
- }
- }
|