123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771 |
- //
- // PQUploadViewController.swift
- // PQSpeed
- //
- // Created by SanW on 2020/8/1.
- // Copyright © 2020 BytesFlow. All rights reserved.
- //
- import MobileCoreServices
- import Photos
- import UIKit
- import BFCommonKit
- let playerHeaderH: CGFloat = cScreenWidth * (250 / 375)
- class PQUploadController: PQBaseViewController {
- // 最大的宽度
- var maxWidth: CGFloat = cScreenWidth
- // 最大的高度
- var maxHeight: CGFloat = adapterWidth(width: 300)
- // 画面比例
- var aspectRatio: aspectRatio?
- var preViewSize: CGSize {
- if aspectRatio == nil, (isMember(of: PQUploadController.self) && selectedData == nil) || (!isMember(of: PQUploadController.self) && uploadData == nil) {
- return CGSize(width: maxHeight, height: maxHeight)
- }
- if selectedData != nil {
- aspectRatio = .origin(width: CGFloat(videoData[lastSeletedIndex?.item ?? 0].videoWidth), height: CGFloat(videoData[lastSeletedIndex?.item ?? 0].videoHeight))
- } else if aspectRatio == nil {
- aspectRatio = .origin(width: CGFloat(uploadData?.videoWidth ?? maxHeight), height: CGFloat(uploadData?.videoHeight ?? maxHeight))
- }
- switch aspectRatio {
- case let .origin(width, height):
- var tempHeight: CGFloat = 0
- var tempWidth: CGFloat = 0
- if width > height {
- tempHeight = (maxWidth * height / width)
- tempWidth = maxWidth
- } else {
- tempHeight = maxHeight
- tempWidth = (maxHeight * width / height)
- }
- if tempHeight.isNaN || tempWidth.isNaN {
- return CGSize.zero
- } else {
- return CGSize(width: tempWidth, height: tempHeight)
- }
- case .oneToOne:
- if maxWidth > maxHeight {
- return CGSize(width: maxHeight, height: maxHeight)
- } else {
- return CGSize(width: maxWidth, height: maxWidth)
- }
- case .sixteenToNine:
- return CGSize(width: maxWidth, height: maxWidth * 9.0 / 16.0)
- case .nineToSixteen:
- return CGSize(width: maxHeight * 9.0 / 16.0, height: maxHeight)
- default:
- break
- }
- return CGSize(width: maxHeight, height: maxHeight)
- }
- // 上传入口类型
- var sourceType: videoUploadSourceType = .videoUpload
- // 制作视频项目Id
- var makeVideoProjectId: String?
- // 再创作数据
- var reCreateData: PQReCreateModel?
- // 视频创作埋点数据
- var eventTrackData: PQVideoMakeEventTrackModel?
- // 制作视频草稿Id
- var makeVideoDraftboxId: String?
- // 制作视频草稿结构化数据
- var makeVideoSdata: String?
- var isAssetImage: Bool = false // 是否请求的是图片
- var videoWidth: CGFloat = 0 // 视频宽
- var videoHeight: CGFloat = 0 // 视频高
- var isLoop: Bool = true // 是否循环播放
- var playerItem: AVPlayerItem? // 当前播放item
- var videoOutput: AVPlayerItemVideoOutput?
- let itemSize = CGSize(width: ((cScreenWidth - cDefaultMargin) / 3) * UIScreen.main.scale, height: ((cScreenWidth - cDefaultMargin) / 3) * UIScreen.main.scale)
- var categoryH: CGFloat = cDefaultMargin * 40 // 相簿高度
- var videoData: [PQUploadModel] = Array<PQUploadModel>.init()
- var categoryData: [PQUploadModel] = Array<PQUploadModel>.init()
- // 当前选中的数据
- var selectedData: PQUploadModel?
- // 确定上传的数据
- var uploadData: PQUploadModel?
- var catagerySelectedIndex: IndexPath = IndexPath(item: 0, section: 0) // 更多图库选择
- var isJumpToAuthorization: Bool = false // 是否跳到授权
- var lastSeletedIndex: IndexPath? // 上次选中的index
- lazy var imageManager: PHCachingImageManager = {
- (PHCachingImageManager.default() as? PHCachingImageManager) ?? PHCachingImageManager()
- }()
- var allPhotos: PHFetchResult<PHAsset>!
- var previousPreheatRect = CGRect.zero
- var smartAlbums: PHFetchResult<PHAssetCollection>!
- var userCollections: PHFetchResult<PHCollection>!
- let sectionLocalizedTitles = ["", NSLocalizedString("Smart Albums", comment: ""), NSLocalizedString("Albums", comment: "")]
- lazy var fetchOptions: PHFetchOptions = {
- let fetchOptions = PHFetchOptions()
- fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
- fetchOptions.predicate = NSPredicate(format: "mediaType = %d", !isAssetImage ? PHAssetMediaType.video.rawValue : PHAssetMediaType.image.rawValue)
- return fetchOptions
- }()
- lazy var imagesOptions: PHImageRequestOptions = {
- let imagesOptions = PHImageRequestOptions()
- imagesOptions.isSynchronous = true
- imagesOptions.isNetworkAccessAllowed = false
- imagesOptions.deliveryMode = .opportunistic
- imagesOptions.resizeMode = .fast
- imagesOptions.progressHandler = { _, _, _, info in
- BFLog(message: "progressHandler = \(info)")
- }
- return imagesOptions
- }()
- lazy var singleImageOptions: PHImageRequestOptions = {
- let singleImageOptions = PHImageRequestOptions()
- singleImageOptions.isSynchronous = true
- singleImageOptions.isNetworkAccessAllowed = false
- singleImageOptions.deliveryMode = .highQualityFormat
- return singleImageOptions
- }()
- lazy var backBtn: UIButton = {
- let backBtn = UIButton(type: .custom)
- backBtn.frame = CGRect(x: 0, y: cDevice_iPhoneStatusBarHei, width: cDefaultMargin * 4, height: cDefaultMargin * 4)
- backBtn.imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: -5, right: 0)
- backBtn.backgroundColor = .yellow
-
- backBtn.setImage(UIImage.moduleImage(named: "icon_blanc_back", moduleName: "BFFramework",isAssets: false), for: .normal)
- backBtn.addTarget(self, action: #selector(backBtnClick), for: .touchUpInside)
- return backBtn
- }()
- var anthorEmptyData: PQEmptyModel? = {
- let anthorEmptyData = PQEmptyModel()
- anthorEmptyData.title = "开始上传"
- anthorEmptyData.summary = "要开始上传视频,请先授予相册使用权限"
- anthorEmptyData.emptyImage = "icon_authorError"
- return anthorEmptyData
- }()
- var emptyData: PQEmptyModel? = {
- let emptyData = PQEmptyModel()
- emptyData.title = "哦呜~ 你没有可上传的视频~"
- emptyData.emptyImage = "video_empty"
- emptyData.netDisRefreshBgColor = UIColor.hexColor(hexadecimal: "#FA6400")
- emptyData.netDisTitle = "内容加载失败"
- emptyData.netDisTitleColor = UIColor.hexColor(hexadecimal: "#333333")
- emptyData.netemptyDisImage = UIImage.init(named: "empty_netDis_icon")
- emptyData.netDisRefreshTitle = NSMutableAttributedString(string: "重新加载", attributes: [.font: UIFont.systemFont(ofSize: 16, weight: .medium), .foregroundColor: UIColor.white])
- return emptyData
- }()
- lazy var emptyRemindView: PQEmptyRemindView = {
- let remindView = PQEmptyRemindView(frame: CGRect(x: 0, y: cDevice_iPhoneNavBarAndStatusBarHei, width: cScreenWidth, height: cScreenHeigth - cDevice_iPhoneNavBarAndStatusBarHei))
- remindView.isHidden = true
- remindView.emptyData = anthorEmptyData
- view.addSubview(remindView)
- remindView.fullRefreshBloc = { [weak self] _, _ in
- self?.isJumpToAuthorization = true
- if self?.emptyRemindView.refreshBtn.currentTitle == "授予权限" {
- openAppSetting()
- }
- }
- return remindView
- }()
- lazy var collectionView: UICollectionView = {
- let layout = UICollectionViewFlowLayout()
- layout.sectionInset = UIEdgeInsets.zero
- let collectionView = UICollectionView(frame: CGRect(x: 0, y: cDevice_iPhoneNavBarAndStatusBarHei, width: cScreenWidth, height: cScreenHeigth - cDevice_iPhoneNavBarAndStatusBarHei), collectionViewLayout: layout)
- collectionView.showsVerticalScrollIndicator = false
- collectionView.register(PQSelecteVideoItemCell.self, forCellWithReuseIdentifier: "PQSelecteVideoItemCell")
- collectionView.delegate = self
- collectionView.dataSource = self
- if #available(iOS 11.0, *) {
- collectionView.contentInsetAdjustmentBehavior = .never
- } else {
- automaticallyAdjustsScrollViewInsets = false
- }
- collectionView.backgroundColor = .clear
- return collectionView
- }()
- lazy var categoryCollectionView: UICollectionView = {
- let layout = UICollectionViewFlowLayout()
- layout.sectionInset = UIEdgeInsets.zero
- let categoryCollectionView = UICollectionView(frame: CGRect(x: 0, y: -categoryH, width: cScreenWidth, height: categoryH), collectionViewLayout: layout)
- categoryCollectionView.showsVerticalScrollIndicator = false
- categoryCollectionView.register(PQAssetCategoryCell.self, forCellWithReuseIdentifier: "PQAssetCategoryCell")
- categoryCollectionView.delegate = self
- categoryCollectionView.dataSource = self
- if #available(iOS 11.0, *) {
- categoryCollectionView.contentInsetAdjustmentBehavior = .never
- } else {
- automaticallyAdjustsScrollViewInsets = false
- }
- categoryCollectionView.backgroundColor = .white
- return categoryCollectionView
- }()
- lazy var categoryView: UIView = {
- let categoryView = UIView(frame: CGRect(x: 0, y: cDevice_iPhoneNavBarAndStatusBarHei, width: cScreenWidth, height: cScreenHeigth - cDevice_iPhoneNavBarAndStatusBarHei))
- categoryView.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.6)
- let bgView = UIView(frame: CGRect(x: 0, y: categoryH, width: categoryView.frame.width, height: categoryView.frame.height - categoryH))
- let ges = UITapGestureRecognizer(target: self, action: #selector(cancelClick))
- bgView.addGestureRecognizer(ges)
- categoryView.addSubview(bgView)
- categoryView.isHidden = true
- return categoryView
- }()
-
- lazy var playBtn: UIButton = {
- let playBtn = UIButton(type: .custom)
- playBtn.frame = CGRect(x: (preViewSize.width - cDefaultMargin * 5) / 2, y: (preViewSize.height - cDefaultMargin * 5) / 2, width: cDefaultMargin * 5, height: cDefaultMargin * 5)
- playBtn.setImage(UIImage(named: "icon_video_play_big"), for: .normal)
- playBtn.tag = 4
- playBtn.isHidden = true
- playBtn.isUserInteractionEnabled = false
- // playBtn.addTarget(self, action: #selector(btnClick(sender:)), for: .touchUpInside)
- return playBtn
- }()
- var playerHeaderView: UIImageView = {
- let playerHeaderView = UIImageView(frame: CGRect(x: 0, y: cDevice_iPhoneNavBarAndStatusBarHei, width: cScreenWidth, height: 0))
- playerHeaderView.isUserInteractionEnabled = true
- playerHeaderView.contentMode = .scaleAspectFit
- playerHeaderView.clipsToBounds = true
- playerHeaderView.backgroundColor = UIColor.yellow
- return playerHeaderView
- }()
- lazy var selecteBtn: UIButton = {
- let selecteBtn = UIButton(frame: CGRect(x: deleteBtn.frame.maxX + cDefaultMargin, y: 0, width: cScreenWidth - nextBtn.frame.width - deleteBtn.frame.maxX - cDefaultMargin * 5, height: cDevice_iPhoneTabBarHei))
- selecteBtn.titleLabel?.lineBreakMode = .byTruncatingTail
- selecteBtn.setTitle("全部", for: .normal)
-
- selecteBtn.setImage(UIImage.moduleImage(named: "icon_uploadVideo_more", moduleName: "BFFramework",isAssets: false), for: .normal)
- selecteBtn.setTitleColor(UIColor.black, for: .normal)
- selecteBtn.titleLabel?.font = UIFont.systemFont(ofSize: 16, weight: .medium)
- selecteBtn.tag = 2
- selecteBtn.imagePosition(at: PQButtonImageEdgeInsetsStyle.right, space: cDefaultMargin / 2)
- selecteBtn.addTarget(self, action: #selector(btnClick(sender:)), for: .touchUpInside)
- return selecteBtn
- }()
- lazy var deleteBtn: UIButton = {
- let deleteBtn = UIButton(frame: CGRect(x: cDefaultMargin, y: 0, width: cDefaultMargin * 4, height: cDevice_iPhoneTabBarHei))
- deleteBtn.setImage(UIImage.moduleImage(named: "icon_blanc_back", moduleName: "BFFramework",isAssets: false), for: .normal)
- deleteBtn.tag = 1
- deleteBtn.addTarget(self, action: #selector(btnClick(sender:)), for: .touchUpInside)
- return deleteBtn
- }()
- lazy var nextBtn: UIButton = {
- let nextBtn = UIButton(frame: CGRect(x: 0, y: (cDevice_iPhoneTabBarHei - cDefaultMargin * 3) / 2, width: cDefaultMargin * 6, height: cDefaultMargin * 3))
- nextBtn.addCorner(corner: 3)
- nextBtn.setTitle("下一步", for: .normal)
- nextBtn.titleLabel?.font = UIFont.systemFont(ofSize: 13, weight: .medium)
- nextBtn.tag = 3
- nextBtn.addTarget(self, action: #selector(btnClick(sender:)), for: .touchUpInside)
- nextBtn.backgroundColor = UIColor.hexColor(hexadecimal: PQBFConfig.shared.styleColor.rawValue)
- nextBtn.setTitleColor(.white, for: .normal)
- return nextBtn
- }()
- lazy var bottomView: UIView = {
- let bottomView = UIView(frame: CGRect(x: 0, y: cDefaultMargin * 2, width: cScreenWidth, height: cDevice_iPhoneNavBarHei))
- bottomView.addSubview(selecteBtn)
- bottomView.backgroundColor = PQBFConfig.shared.styleBackGroundColor
- selecteBtn.center.y = nextBtn.center.y
- bottomView.addSubview(deleteBtn)
- bottomView.addSubview(nextBtn)
- nextBtn.frame.origin.x = bottomView.frame.width - nextBtn.frame.width - cDefaultMargin * 2
- return bottomView
- }()
- override func viewDidLoad() {
- super.viewDidLoad()
- view.backgroundColor = .white
- navHeadImageView?.backgroundColor = .white
- lineView?.backgroundColor = .white
- addSubViews()
- loadLocalData()
- }
- deinit {
- // PHPhotoLibrary.shared().unregisterChangeObserver(self)
- }
- override func viewDidDisappear(_ animated: Bool) {
- super.viewDidDisappear(animated)
-
- }
- override func viewWillAppear(_ animated: Bool) {
- super.viewDidAppear(animated)
-
- addPlayerItemObserver()
- }
- override func viewWillDisappear(_ animated: Bool) {
- super.viewWillDisappear(animated)
- removePlayerItemObserver()
- }
- func addSubViews() {
- view.addSubview(collectionView)
- navHeadImageView?.addSubview(bottomView)
-
- PQNotification.addObserver(self, selector: #selector(didBecomeActiveNotification), name: UIApplication.didBecomeActiveNotification, object: nil)
- }
- func loadLocalData() {
- let authStatus = PHPhotoLibrary.authorizationStatus()
- if authStatus == .notDetermined {
- // 第一次触发授权 alert
- PHPhotoLibrary.requestAuthorization { [weak self] (status: PHAuthorizationStatus) -> Void in
- if status == .authorized {
- if (self?.allPhotos == nil) || (self?.allPhotos.count ?? 0) <= 0 {
- self?.loadPhotoData()
- }
- if self?.backBtn != nil {
- self?.backBtn.removeFromSuperview()
- }
- } else {
- DispatchQueue.main.async { [weak self] in
- self?.emptyRemindView.isHidden = false
- self?.emptyRemindView.refreshBtn.isHidden = false
- self?.emptyRemindView.refreshBtn.setTitle("授予权限", for: .normal)
- if self?.backBtn.superview == nil {
- self?.view.addSubview((self?.backBtn)!)
- } else {
- self?.backBtn.isHidden = false
- }
- }
- }
- }
- } else if authStatus == .authorized {
- if allPhotos == nil || allPhotos.count <= 0 {
- loadPhotoData()
- }
- if backBtn.superview != nil {
- backBtn.removeFromSuperview()
- }
- } else {
- emptyRemindView.isHidden = false
- emptyRemindView.refreshBtn.isHidden = false
- emptyRemindView.refreshBtn.setTitle("授予权限", for: .normal)
- if backBtn.superview == nil {
- view.addSubview(backBtn)
- } else {
- backBtn.isHidden = false
- }
- }
- }
- func loadPhotoData() {
- DispatchQueue.main.async { [weak self] in
- PQLoadingHUB.shared.showHUB(superView: self!.view, isVerticality: false)
- }
- DispatchQueue.global().async { [weak self] in
- self?.allPhotos = PHAsset.fetchAssets(with: self?.fetchOptions)
- DispatchQueue.main.async { [weak self] in
- if self?.view != nil {
- PQLoadingHUB.shared.dismissHUB(superView: self!.view)
- }
- self?.collectionView.reloadData()
- if (self?.allPhotos.count ?? 0) <= 0 {
- self?.emptyRemindView.frame = CGRect(x: 0, y: cDevice_iPhoneNavBarAndStatusBarHei, width: cScreenWidth, height: cScreenHeigth - cDevice_iPhoneNavBarAndStatusBarHei - cDevice_iPhoneTabBarHei)
- self?.emptyRemindView.emptyData = self?.emptyData
- self?.emptyRemindView.isHidden = false
- } else {
- self?.emptyRemindView.isHidden = true
- }
- if (self?.allPhotos.count ?? 0) > 0 {
- let tempData = PQUploadModel()
- tempData.title = "全部"
- tempData.categoryList = self!.allPhotos
- self?.categoryData.insert(tempData, at: 0)
- }
- self?.updateCachedAssets()
- }
- }
- PHPhotoLibrary.shared().register(self)
- DispatchQueue.global().async { [weak self] in
- self?.smartAlbums = PHAssetCollection.fetchAssetCollections(with: .smartAlbum, subtype: .albumRegular, options: nil)
- self?.smartAlbums?.enumerateObjects { [weak self] assCollection, _, _ in
- if assCollection.localizedTitle != "最近删除" {
- self?.convertCollection(collection: assCollection)
- }
- }
- self?.userCollections = PHCollectionList.fetchTopLevelUserCollections(with: nil)
- self?.userCollections.enumerateObjects { assCollection, index, point in
- BFLog(message: "userCollections == \(assCollection),index = \(index),point = \(point)")
- if assCollection is PHAssetCollection {
- if assCollection.localizedTitle != "最近删除" {
- self?.convertCollection(collection: assCollection as? PHAssetCollection)
- }
- }
- }
- }
-
- }
- // 转化处理获取到的相簿
- func convertCollection(collection: PHAssetCollection?) {
- if collection == nil {
- return
- }
- DispatchQueue.global().async { [weak self] in
- let assetsFetchResult = PHAsset.fetchAssets(in: collection!, options: self?.fetchOptions)
- if assetsFetchResult.count > 0 {
- let tempData = PQUploadModel()
- tempData.title = collection?.localizedTitle
- tempData.categoryList = assetsFetchResult
- if tempData.categoryList.count > 0 {
- self?.categoryData.append(tempData)
- }
- BFLog(message: "assetsFetchResult = \(assetsFetchResult)")
- }
- }
- }
- @objc func btnClick(sender: UIButton) {
- switch sender.tag {
- case 1: // 返回
- navigationController?.popViewController(animated: true)
-
- case 2: // 筛选
- showCollects()
- case 3: // 下一步
- if selectedData == nil {
- cShowHUB(superView: nil, msg: isAssetImage ? "请选择图片" : "请选择视频")
- return
- }
-
- imageManager.requestImage(for: (selectedData?.asset)!, targetSize: itemSize, contentMode: .aspectFill, options: nil) { [weak self] image, _ in
- self?.selectedData?.image = image
- let vc = PQImageCropVC(image: (self?.selectedData?.image)!, aspectWidth: self?.videoWidth ?? 0.0, aspectHeight: self?.videoHeight ?? 0.0)
- vc.uploadData = self?.selectedData
- self?.navigationController?.pushViewController(vc, animated: true)
- }
- default:
- break
- }
- }
- @objc func showCollects() {
- if categoryData.count <= 0 {
- return
- }
- categoryCollectionView.reloadData()
- if categoryView.superview == nil {
- view.insertSubview(categoryView, belowSubview: navHeadImageView!)
- categoryView.addSubview(categoryCollectionView)
- showCategoryView()
- return
- }
- if categoryView.isHidden {
- showCategoryView()
- } else {
- cancelClick()
- }
- }
- @objc func showCategoryView() {
- categoryView.isHidden = false
- categoryView.alpha = 0
- view.bringSubviewToFront(categoryView)
- view.bringSubviewToFront(bottomView)
- UIView.animate(withDuration: 0.3, animations: {
- self.categoryCollectionView.frame = CGRect(x: 0, y: 0, width: cScreenWidth, height: self.categoryH)
- self.categoryView.alpha = 1
- }) { _ in
- }
- }
- @objc func cancelClick() {
- UIView.animate(withDuration: 0.3, animations: {
- self.categoryCollectionView.frame = CGRect(x: 0, y: -self.categoryH, width: cScreenWidth, height: self.categoryH)
- self.categoryView.alpha = 0
- }) { _ in
- self.categoryView.isHidden = true
- }
- }
-
-
- @objc func didBecomeActiveNotification() {
- if isJumpToAuthorization {
- loadLocalData()
- isJumpToAuthorization = false
- }
- }
-
- }
- extension PQUploadController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, UIScrollViewDelegate {
- func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection _: Int) -> Int {
- if collectionView == self.collectionView {
- return allPhotos == nil ? videoData.count : allPhotos.count
- }
- return categoryData.count
- }
- func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
- if collectionView == self.collectionView {
- let cell = PQSelecteVideoItemCell.selecteVideoItemCell(collectionView: collectionView, indexPath: indexPath)
- if videoData.count <= indexPath.item, allPhotos != nil {
- let itemData = PQUploadModel()
- // itemData.image = UIImage.init(named: "cut_place")
- let asset = allPhotos.object(at: indexPath.item)
- itemData.asset = asset
- itemData.duration = asset.duration
- videoData.append(itemData)
- }
- if videoData.count > indexPath.item {
- let itemData = videoData[indexPath.item]
- cell.uploadData = itemData
- if itemData.image == nil, itemData.asset != nil {
- cell.representedAssetIdentifier = itemData.asset?.localIdentifier
- imageManager.requestImage(for: itemData.asset!, targetSize: itemSize, contentMode: .aspectFill, options: nil) { image, info in
- if info?.keys.contains("PHImageResultIsDegradedKey") ?? false, "\(info?["PHImageResultIsDegradedKey"] ?? "0")" == "0", cell.representedAssetIdentifier == itemData.asset?.localIdentifier {
- if image != nil {
- itemData.image = image
- cell.videoImageView.image = image
- } else if image == nil, info?.keys.contains("PHImageResultIsInCloudKey") ?? false {
- let option = PHImageRequestOptions()
- option.isNetworkAccessAllowed = true
- option.resizeMode = .fast
- self.imageManager.requestImageData(for: itemData.asset!, options: option) { data, _, _, _ in
- if data != nil {
- let image = UIImage(data: data!)
- itemData.image = image
- cell.videoImageView.image = image
- }
- }
- }
- }
- }
- }
- } else {
- cell.uploadData = PQUploadModel()
- }
- return cell
- } else {
- let cell = PQAssetCategoryCell.assetCategoryCell(collectionView: collectionView, indexPath: indexPath)
- let itemData = categoryData[indexPath.item]
- let asset = itemData.categoryList.object(at: 0)
- if itemData.image == nil {
- cell.representedAssetIdentifier = asset.localIdentifier
- imageManager.requestImage(for: asset, targetSize: itemSize, contentMode: .aspectFill, options: nil) { image, info in
- if info?.keys.contains("PHImageResultIsDegradedKey") ?? false, "\(info?["PHImageResultIsDegradedKey"] ?? "0")" == "0", cell.representedAssetIdentifier == asset.localIdentifier {
- itemData.image = image
- cell.uploadData = itemData
- }
- }
- } else {
- cell.uploadData = itemData
- }
- cell.isSelected = indexPath == catagerySelectedIndex
- return cell
- }
- }
- func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
- if collectionView == self.collectionView {
- if videoData.count <= indexPath.item {
- return
- }
- let itemData = videoData[indexPath.item]
-
- let ratio = Float(itemData.asset?.pixelWidth ?? 0) / Float(itemData.asset?.pixelHeight ?? 1)
- if ratio < 0.4 || ratio > 4.2 {
- cShowHUB(superView: nil, msg: "暂不支持该比例的素材")
- return
- }
- if lastSeletedIndex != nil, lastSeletedIndex != indexPath {
- let lastData = videoData[lastSeletedIndex!.item]
- lastData.isSelected = false
- collectionView.reloadItems(at: [lastSeletedIndex!])
- }
- lastSeletedIndex = indexPath
- if itemData.isSelected {
- itemData.isSelected = false
- selectedData = nil
-
- } else {
- itemData.isSelected = true
- let itemData = videoData[indexPath.item]
-
- selectedData = itemData
-
- }
-
- collectionView.reloadItems(at: [indexPath])
- } else {
- videoData.removeAll()
- self.collectionView.setContentOffset(CGPoint.zero, animated: true)
- self.collectionView.reloadData()
- allPhotos = categoryData[indexPath.item].categoryList
- catagerySelectedIndex = indexPath
- selecteBtn.setTitle(categoryData[indexPath.item].title, for: .normal)
- selecteBtn.imagePosition(at: PQButtonImageEdgeInsetsStyle.right, space: cDefaultMargin / 2)
-
- lastSeletedIndex = nil
-
- if allPhotos.count <= 0 {
- emptyRemindView.frame = CGRect(x: 0, y: cDevice_iPhoneNavBarAndStatusBarHei, width: cScreenWidth, height: cScreenHeigth - cDevice_iPhoneNavBarAndStatusBarHei - cDevice_iPhoneTabBarHei)
- emptyRemindView.emptyData = emptyData
- emptyRemindView.isHidden = false
- } else {
- emptyRemindView.isHidden = true
- }
- self.collectionView.reloadData()
- cancelClick()
- }
- }
- func collectionView(_ collectionView: UICollectionView, layout _: UICollectionViewLayout, sizeForItemAt _: IndexPath) -> CGSize {
- if collectionView == self.collectionView {
- return CGSize(width: (cScreenWidth - cDefaultMargin) / 3, height: (cScreenWidth - cDefaultMargin) / 3)
- }
- return CGSize(width: collectionView.frame.width, height: cDefaultMargin * 8)
- }
- func collectionView(_ collectionView: UICollectionView, layout _: UICollectionViewLayout, minimumLineSpacingForSectionAt _: Int) -> CGFloat {
- if collectionView == self.collectionView {
- return cDefaultMargin / 2
- }
- return 0
- }
- func collectionView(_ collectionView: UICollectionView, layout _: UICollectionViewLayout, minimumInteritemSpacingForSectionAt _: Int) -> CGFloat {
- if collectionView == self.collectionView {
- return cDefaultMargin / 2
- }
- return 0
- }
- func scrollViewDidScroll(_ scrollView: UIScrollView) {
- //这里是不是有用的?
- // if currentController() is PQUploadController || currentController() is PQImageSelectedController {
- // if scrollView == collectionView {
- // updateCachedAssets()
- // } else {
- // BFLog(message: "contentOffset = \(scrollView.contentOffset),contentSize = \(scrollView.contentSize)")
- // if scrollView.contentOffset.y > ((scrollView.contentSize.height - scrollView.frame.height) + cDefaultMargin * 10) {
- // cancelClick()
- // }
- // }
- // }
- }
- }
- extension PQUploadController: PHPhotoLibraryChangeObserver {
- func photoLibraryDidChange(_ changeInstance: PHChange) {
- // Change notifications may be made on a background queue. Re-dispatch to the
- // main queue before acting on the change as we'll be updating the UI.
- DispatchQueue.main.sync { [weak self] in
- // Check each of the three top-level fetches for changes.
- if allPhotos != nil, changeInstance.changeDetails(for: allPhotos) != nil {
- self?.categoryData.removeAll()
- self?.loadPhotoData()
- }
- }
- }
- }
- extension PQUploadController {
- /// 添加监听
- /// - Parameter playerItem: <#playerItem description#>
- /// - Returns: <#description#>
- func addPlayerItemObserver() {
- playerItem?.addObserver(self, forKeyPath: "status", options: .new, context: nil)
- }
- /// 移除监听
- /// - Returns: <#description#>
- func removePlayerItemObserver() {
- playerItem?.removeObserver(self, forKeyPath: "status")
- }
- override func observeValue(forKeyPath keyPath: String?, of object: Any?, change _: [NSKeyValueChangeKey: Any]?, context _: UnsafeMutableRawPointer?) {
- if object is AVPlayerItem, keyPath == "status" {
- BFLog(message: "(object as! AVPlayerItem).status = \((object as! AVPlayerItem).status.rawValue)")
- PQLoadingHUB.shared.dismissHUB(superView: playerHeaderView)
- switch (object as! AVPlayerItem).status {
- case .unknown:
- break
- case .readyToPlay:
- break
- case .failed:
- break
- default:
- break
- }
- }
- }
- private func resetCachedAssets() {
- imageManager.stopCachingImagesForAllAssets()
- previousPreheatRect = .zero
- }
- private func updateCachedAssets() {
- if allPhotos != nil && allPhotos.count <= 0 {
- return
- }
- guard isViewLoaded, view.window != nil else { return }
- let visibleRect = CGRect(origin: collectionView.contentOffset, size: collectionView.bounds.size)
- let preheatRect = visibleRect.insetBy(dx: 0, dy: -0.5 * visibleRect.height)
- let delta = abs(preheatRect.midY - previousPreheatRect.midY)
- guard delta > view.bounds.height / 3 else { return }
- let (addedRects, removedRects) = differencesBetweenRects(previousPreheatRect, preheatRect)
- let addedAssets = addedRects
- .flatMap { rect in collectionView.indexPathsForElements(in: rect) }
- .map { indexPath in allPhotos.object(at: indexPath.item) }
- let removedAssets = removedRects
- .flatMap { rect in collectionView.indexPathsForElements(in: rect) }
- .map { indexPath in allPhotos.object(at: indexPath.item) }
- imageManager.startCachingImages(for: addedAssets,
- targetSize: itemSize, contentMode: .aspectFill, options: nil)
- imageManager.stopCachingImages(for: removedAssets,
- targetSize: itemSize, contentMode: .aspectFill, options: nil)
- previousPreheatRect = preheatRect
- }
- private func differencesBetweenRects(_ old: CGRect, _ new: CGRect) -> (added: [CGRect], removed: [CGRect]) {
- if old.intersects(new) {
- var added = [CGRect]()
- if new.maxY > old.maxY {
- added += [CGRect(x: new.origin.x, y: old.maxY,
- width: new.width, height: new.maxY - old.maxY)]
- }
- if old.minY > new.minY {
- added += [CGRect(x: new.origin.x, y: new.minY,
- width: new.width, height: old.minY - new.minY)]
- }
- var removed = [CGRect]()
- if new.maxY < old.maxY {
- removed += [CGRect(x: new.origin.x, y: new.maxY,
- width: new.width, height: old.maxY - new.maxY)]
- }
- if old.minY < new.minY {
- removed += [CGRect(x: new.origin.x, y: old.minY,
- width: new.width, height: new.minY - old.minY)]
- }
- return (added, removed)
- } else {
- return ([new], [old])
- }
- }
- }
-
|