128 lines
4.6 KiB
Swift
128 lines
4.6 KiB
Swift
//
|
||
// CloudDrivePreviewViewController.swift
|
||
// suixinkan
|
||
//
|
||
|
||
import AVKit
|
||
import Kingfisher
|
||
import SnapKit
|
||
import UIKit
|
||
|
||
/// 云盘文件预览页,严格对齐 Android 黑底预览并保留 iOS 原生视频控制层。
|
||
final class CloudDrivePreviewViewController: BaseViewController {
|
||
private let file: CloudFile
|
||
private let imageView = UIImageView()
|
||
private var playerViewController: AVPlayerViewController?
|
||
private var previousStandardAppearance: UINavigationBarAppearance?
|
||
private var previousScrollEdgeAppearance: UINavigationBarAppearance?
|
||
private var previousCompactAppearance: UINavigationBarAppearance?
|
||
private var previousTintColor: UIColor?
|
||
|
||
/// 初始化云盘文件预览页。
|
||
init(file: CloudFile) {
|
||
self.file = file
|
||
super.init(nibName: nil, bundle: nil)
|
||
}
|
||
|
||
@available(*, unavailable)
|
||
required init?(coder: NSCoder) {
|
||
fatalError("init(coder:) has not been implemented")
|
||
}
|
||
|
||
override var preferredStatusBarStyle: UIStatusBarStyle {
|
||
.lightContent
|
||
}
|
||
|
||
override func setupNavigationBar() {
|
||
navigationItem.titleView = UIView()
|
||
navigationItem.hidesBackButton = true
|
||
let backButton = UIButton(type: .system)
|
||
backButton.setImage(
|
||
UIImage(systemName: "chevron.left")?.withConfiguration(UIImage.SymbolConfiguration(pointSize: 20, weight: .medium)),
|
||
for: .normal
|
||
)
|
||
backButton.tintColor = .white
|
||
backButton.accessibilityLabel = "返回"
|
||
backButton.addTarget(self, action: #selector(backTapped), for: .touchUpInside)
|
||
backButton.snp.makeConstraints { make in make.width.height.equalTo(44) }
|
||
navigationItem.leftBarButtonItem = UIBarButtonItem(customView: backButton)
|
||
}
|
||
|
||
override func setupUI() {
|
||
view.backgroundColor = .black
|
||
if file.isVideo {
|
||
setupVideo()
|
||
} else {
|
||
setupImage()
|
||
}
|
||
}
|
||
|
||
override func viewWillAppear(_ animated: Bool) {
|
||
super.viewWillAppear(animated)
|
||
applyTransparentNavigationBar()
|
||
setNeedsStatusBarAppearanceUpdate()
|
||
}
|
||
|
||
override func viewWillDisappear(_ animated: Bool) {
|
||
super.viewWillDisappear(animated)
|
||
restoreNavigationBar()
|
||
playerViewController?.player?.pause()
|
||
}
|
||
|
||
private func setupImage() {
|
||
imageView.contentMode = .scaleAspectFit
|
||
imageView.backgroundColor = .black
|
||
imageView.accessibilityLabel = file.name
|
||
view.addSubview(imageView)
|
||
imageView.snp.makeConstraints { make in make.edges.equalTo(view.safeAreaLayoutGuide) }
|
||
if let url = URL(string: file.fileUrl), !file.fileUrl.isEmpty {
|
||
imageView.kf.setImage(with: url)
|
||
}
|
||
}
|
||
|
||
private func setupVideo() {
|
||
guard let url = URL(string: file.fileUrl), !file.fileUrl.isEmpty else { return }
|
||
let player = AVPlayer(url: url)
|
||
let controller = AVPlayerViewController()
|
||
controller.player = player
|
||
controller.view.backgroundColor = .black
|
||
addChild(controller)
|
||
view.addSubview(controller.view)
|
||
controller.view.snp.makeConstraints { make in make.edges.equalTo(view.safeAreaLayoutGuide) }
|
||
controller.didMove(toParent: self)
|
||
playerViewController = controller
|
||
player.play()
|
||
}
|
||
|
||
private func applyTransparentNavigationBar() {
|
||
guard let navigationBar = navigationController?.navigationBar else { return }
|
||
previousStandardAppearance = navigationBar.standardAppearance
|
||
previousScrollEdgeAppearance = navigationBar.scrollEdgeAppearance
|
||
previousCompactAppearance = navigationBar.compactAppearance
|
||
previousTintColor = navigationBar.tintColor
|
||
|
||
let appearance = UINavigationBarAppearance()
|
||
appearance.configureWithTransparentBackground()
|
||
appearance.backgroundColor = .clear
|
||
appearance.shadowColor = .clear
|
||
navigationBar.standardAppearance = appearance
|
||
navigationBar.scrollEdgeAppearance = appearance
|
||
navigationBar.compactAppearance = appearance
|
||
navigationBar.tintColor = .white
|
||
}
|
||
|
||
private func restoreNavigationBar() {
|
||
guard let navigationBar = navigationController?.navigationBar else { return }
|
||
if let previousStandardAppearance {
|
||
navigationBar.standardAppearance = previousStandardAppearance
|
||
}
|
||
navigationBar.scrollEdgeAppearance = previousScrollEdgeAppearance
|
||
navigationBar.compactAppearance = previousCompactAppearance
|
||
navigationBar.tintColor = previousTintColor
|
||
}
|
||
|
||
@objc private func backTapped() {
|
||
navigationController?.popViewController(animated: true)
|
||
}
|
||
}
|