Selaa lähdekoodia

Merge branch 'master' of https://git.yishihui.com/iOS/BFFramework
合并代码

jsonwang 3 vuotta sitten
vanhempi
commit
83bf0780ab

+ 1 - 1
BFFramework/Classes/BFModules/BFUtility/PQSingletoRealmUtil.swift

@@ -12,7 +12,7 @@ import BFCommonKit
 import BFUIKit
 
 public class PQSingletoRealmUtil: NSObject {
-    public  var schemaVersion : UInt64 = 33
+    public  var schemaVersion : UInt64 = 40
     public var realmEntry: Realm? {
         let config = Realm.Configuration(
             schemaVersion: schemaVersion,

+ 5 - 5
BFFramework/Classes/PModels/editDarftModels/PQEditVisionTrackMaterialsModel.swift

@@ -256,27 +256,27 @@ public class PQEditVisionTrackMaterialsModel: PQEditBaseModel {
         }
         BFLog(message: " locationPath is\(documensDirectory + locationPath)")
         if type != StickerType.VIDEO.rawValue {
-            var coverImage = UIImage(contentsOfFile: documensDirectory + locationPath)
+            let tempPath = (locationPath.contains("var/mobile/Media") ? locationPath:  documensDirectory + locationPath)
+            var coverImage = UIImage(contentsOfFile: tempPath)
 
             if coverImage == nil {
                 // 有可能是 WEBP
                 var fileData: Data?
-                if fileIsExists(filePath: documensDirectory + locationPath) {
-                    fileData = try! Data(contentsOf: URL(fileURLWithPath: documensDirectory + locationPath))
+                if fileIsExists(filePath: tempPath) {
+                    fileData = try! Data(contentsOf: URL(fileURLWithPath: tempPath))
                 }
                 if fileData != nil && (fileData?.count ?? 0) > 0 && fileData?.isWebPFormat ?? false {
                     BFLog(message: "这个资源为web!")
                     coverImage = WebPProcessor.default.process(item: ImageProcessItem.data(fileData!), options: KingfisherParsedOptionsInfo([.onlyLoadFirstFrame, .scaleFactor(1)]))
                 }
             }
-
             return coverImage
         } else {
             if coverImageUI != nil {
                 BFLog(message: "已经有封面了")
                 return coverImageUI
             } else {
-                return PQVideoSnapshotUtil.videoSnapshot(videoURL: URL(fileURLWithPath: documensDirectory + locationPath), time: 0)
+                return PQVideoSnapshotUtil.videoSnapshot(videoURL: URL(fileURLWithPath: (locationPath.contains("var/mobile/Media") ? locationPath:  documensDirectory + locationPath)), time: 0)
             }
         }
     }

+ 124 - 68
BFFramework/Classes/selectImage/PQUploadController.swift

@@ -13,14 +13,14 @@ import BFUIKit
 
 let playerHeaderH: CGFloat = cScreenWidth * (250 / 375)
 
-class PQUploadController: BFBaseViewController {
+open class PQUploadController: BFBaseViewController {
     // 最大的宽度
-    var maxWidth: CGFloat = cScreenWidth
+    public var maxWidth: CGFloat = cScreenWidth
     // 最大的高度
-    var maxHeight: CGFloat = adapterWidth(width: 300)
+    public var maxHeight: CGFloat = adapterWidth(width: 300)
     // 画面比例
-    var aspectRatio: aspectRatio?
-    var preViewSize: CGSize {
+    public var aspectRatio: aspectRatio?
+    public var preViewSize: CGSize {
         if aspectRatio == nil, (isMember(of: PQUploadController.self) && selectedData == nil) || (!isMember(of: PQUploadController.self) && uploadData == nil) {
             return CGSize(width: maxHeight, height: maxHeight)
         }
@@ -62,56 +62,56 @@ class PQUploadController: BFBaseViewController {
     }
 
     // 上传入口类型
-    var sourceType: videoUploadSourceType = .videoUpload
+    public var sourceType: videoUploadSourceType = .videoUpload
     // 制作视频项目Id
-    var makeVideoProjectId: String?
+    public var makeVideoProjectId: String?
     // 再创作数据
-    var reCreateData: PQReCreateModel?
+    public var reCreateData: PQReCreateModel?
     // 视频创作埋点数据
-    var eventTrackData: PQVideoMakeEventTrackModel?
+    public var eventTrackData: PQVideoMakeEventTrackModel?
     // 制作视频草稿Id
-    var makeVideoDraftboxId: String?
+    public 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?
+    public var makeVideoSdata: String?
+    public var isAssetImage: Bool = false // 是否请求的是图片
+    public var videoWidth: CGFloat = 0 // 视频宽
+    public var videoHeight: CGFloat = 0 // 视频高
+    public var isLoop: Bool = true // 是否循环播放
+    public var playerItem: AVPlayerItem? // 当前播放item
+    public 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 // 相簿高度
+    public var categoryH: CGFloat = cDefaultMargin * 40 // 相簿高度
 
-    var videoData: [PQUploadModel] = Array<PQUploadModel>.init()
+    public var videoData: [PQUploadModel] = Array<PQUploadModel>.init()
 
-    var categoryData: [PQUploadModel] = Array<PQUploadModel>.init()
+    public var categoryData: [PQUploadModel] = Array<PQUploadModel>.init()
 
     // 当前选中的数据
-    var selectedData: PQUploadModel?
+    public var selectedData: PQUploadModel?
     // 确定上传的数据
-    var uploadData: PQUploadModel?
-    var catagerySelectedIndex: IndexPath = IndexPath(item: 0, section: 0) // 更多图库选择
+    public var uploadData: PQUploadModel?
+    public var catagerySelectedIndex: IndexPath = IndexPath(item: 0, section: 0) // 更多图库选择
 
-    var isJumpToAuthorization: Bool = false // 是否跳到授权
-    var lastSeletedIndex: IndexPath? // 上次选中的index
-    lazy var imageManager: PHCachingImageManager = {
+    public var isJumpToAuthorization: Bool = false // 是否跳到授权
+    public var lastSeletedIndex: IndexPath? // 上次选中的index
+    public lazy var imageManager: PHCachingImageManager = {
         (PHCachingImageManager.default() as? PHCachingImageManager) ?? PHCachingImageManager()
     }()
 
-    var allPhotos: PHFetchResult<PHAsset>!
-    var previousPreheatRect = CGRect.zero
+    public var allPhotos: PHFetchResult<PHAsset>!
+    public 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 = {
+    public var smartAlbums: PHFetchResult<PHAssetCollection>!
+    public var userCollections: PHFetchResult<PHCollection>!
+    public let sectionLocalizedTitles = ["", NSLocalizedString("Smart Albums", comment: ""), NSLocalizedString("Albums", comment: "")]
+    public 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 = {
+    public lazy var imagesOptions: PHImageRequestOptions = {
         let imagesOptions = PHImageRequestOptions()
         imagesOptions.isSynchronous = true
         imagesOptions.isNetworkAccessAllowed = false
@@ -123,7 +123,7 @@ class PQUploadController: BFBaseViewController {
         return imagesOptions
     }()
 
-    lazy var singleImageOptions: PHImageRequestOptions = {
+    public lazy var singleImageOptions: PHImageRequestOptions = {
         let singleImageOptions = PHImageRequestOptions()
         singleImageOptions.isSynchronous = true
         singleImageOptions.isNetworkAccessAllowed = false
@@ -131,7 +131,7 @@ class PQUploadController: BFBaseViewController {
         return singleImageOptions
     }()
 
-    lazy var backBtn: UIButton = {
+    public 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)
@@ -142,7 +142,7 @@ class PQUploadController: BFBaseViewController {
         return backBtn
     }()
 
-    var anthorEmptyData: BFEmptyModel? = {
+    public var anthorEmptyData: BFEmptyModel? = {
         let anthorEmptyData = BFEmptyModel()
         anthorEmptyData.title = "开始上传"
         anthorEmptyData.summary = "要开始上传视频,请先授予相册使用权限"
@@ -150,7 +150,7 @@ class PQUploadController: BFBaseViewController {
         return anthorEmptyData
     }()
 
-    var emptyData: BFEmptyModel? = {
+    public var emptyData: BFEmptyModel? = {
         let emptyData = BFEmptyModel()
         emptyData.title = "哦呜~ 你没有可上传的视频~"
         emptyData.emptyImageName = "video_empty"
@@ -162,7 +162,7 @@ class PQUploadController: BFBaseViewController {
         return emptyData
     }()
 
-    lazy var emptyRemindView: BFEmptyRemindView = {
+    public lazy var emptyRemindView: BFEmptyRemindView = {
         let remindView = BFEmptyRemindView(frame: CGRect(x: 0, y: cDevice_iPhoneNavBarAndStatusBarHei, width: cScreenWidth, height: cScreenHeigth - cDevice_iPhoneNavBarAndStatusBarHei))
         remindView.isHidden = true
         remindView.emptyData = anthorEmptyData
@@ -176,7 +176,7 @@ class PQUploadController: BFBaseViewController {
         return remindView
     }()
 
-    lazy var collectionView: UICollectionView = {
+    public 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)
@@ -193,7 +193,7 @@ class PQUploadController: BFBaseViewController {
         return collectionView
     }()
 
-    lazy var categoryCollectionView: UICollectionView = {
+    public 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)
@@ -210,7 +210,7 @@ class PQUploadController: BFBaseViewController {
         return categoryCollectionView
     }()
 
-    lazy var categoryView: UIView = {
+    public 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))
@@ -221,9 +221,63 @@ class PQUploadController: BFBaseViewController {
         return categoryView
     }()
 
- 
+    public lazy var avPlayer: AVPlayer = {
+        let avPlayer = AVPlayer()
+        NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: avPlayer.currentItem, queue: .main) { [weak self] notify in
+            BFLog(message: "AVPlayerItemDidPlayToEndTime = \(notify)")
+            avPlayer.seek(to: CMTime.zero)
+            if self?.isLoop ?? false, bf_getCurrentViewController()?.isMember(of: PQUploadController.self) ?? false {
+                if self?.playerLayer.superlayer == nil {
+                    self?.playerHeaderView.layer.insertSublayer(self!.playerLayer, at: 0)
+                }
+                avPlayer.play()
+            } else {
+                self?.sliderView.setValue(1.0, animated: false)
+                self?.playBtn.isHidden = false
+            }
+        }
+        NotificationCenter.default.addObserver(forName: .AVPlayerItemNewErrorLogEntry, object: avPlayer.currentItem, queue: .main) { notify in
+            BFLog(message: "AVPlayerItemNewErrorLogEntry = \(notify)")
+        }
+        NotificationCenter.default.addObserver(forName: .AVPlayerItemFailedToPlayToEndTime, object: avPlayer.currentItem, queue: .main) { notify in
+            BFLog(message: "AVPlayerItemFailedToPlayToEndTime = \(notify)")
+        }
+        NotificationCenter.default.addObserver(forName: .AVPlayerItemPlaybackStalled, object: avPlayer.currentItem, queue: .main) { notify in
+            BFLog(message: "AVPlayerItemPlaybackStalled = \(notify)")
+        }
+        avPlayer.addPeriodicTimeObserver(forInterval: CMTime(value: 1, timescale: 1000), queue: .main) { [weak self] _ in
+            let progress = CMTimeGetSeconds(avPlayer.currentItem?.currentTime() ?? CMTime.zero) / CMTimeGetSeconds(avPlayer.currentItem?.duration ?? CMTime.zero)
+            self?.sliderView.setValue(Float(progress), animated: false)
+            if progress >= 1, !(self?.isLoop ?? false) {
+                self?.sliderView.setValue(Float(progress), animated: false)
+                self?.playBtn.isHidden = false
+            }
+        }
+        return avPlayer
+    }()
+
+    public lazy var playerLayer: AVPlayerLayer = {
+        let playerLayer = AVPlayerLayer(player: avPlayer)
+        playerLayer.frame = CGRect(origin: CGPoint.zero, size: preViewSize)
+        return playerLayer
+    }()
+
+    public lazy var sliderView: BFPlayerSlider = {
+        let sliderView = BFPlayerSlider(frame: CGRect(x: 0, y: cDevice_iPhoneNavBarAndStatusBarHei + maxHeight, width: view.frame.width, height: cDefaultMargin))
+        let thbImage = UIImage(named: "icon_point")
+        sliderView.setMinimumTrackImage(thbImage, for: .normal)
+        sliderView.setMaximumTrackImage(thbImage, for: .normal)
+        sliderView.setThumbImage(thbImage, for: .highlighted)
+        sliderView.setThumbImage(thbImage, for: .normal)
+        sliderView.maximumTrackTintColor = UIColor.clear
+        sliderView.addTarget(self, action: #selector(sliderValueDidChanged(sender:)), for: .valueChanged)
+        sliderView.minimumTrackTintColor = UIColor.white
+        sliderView.isHidden = true
+        sliderView.backgroundColor = UIColor.black
+        return sliderView
+    }()
 
-    lazy var playBtn: UIButton = {
+    public 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)
@@ -234,7 +288,7 @@ class PQUploadController: BFBaseViewController {
         return playBtn
     }()
 
-    var playerHeaderView: UIImageView = {
+   public var playerHeaderView: UIImageView = {
         let playerHeaderView = UIImageView(frame: CGRect(x: 0, y: cDevice_iPhoneNavBarAndStatusBarHei, width: cScreenWidth, height: 0))
         playerHeaderView.isUserInteractionEnabled = true
         playerHeaderView.contentMode = .scaleAspectFit
@@ -243,7 +297,7 @@ class PQUploadController: BFBaseViewController {
         return playerHeaderView
     }()
 
-    lazy var selecteBtn: UIButton = {
+    public 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)
@@ -258,7 +312,7 @@ class PQUploadController: BFBaseViewController {
         return selecteBtn
     }()
 
-    lazy var deleteBtn: UIButton = {
+    public 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)?.withRenderingMode(.alwaysTemplate), for: .normal)
         deleteBtn.tag = 1
@@ -267,7 +321,7 @@ class PQUploadController: BFBaseViewController {
         return deleteBtn
     }()
 
-    lazy var nextBtn: UIButton = {
+    public 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)
@@ -279,7 +333,7 @@ class PQUploadController: BFBaseViewController {
         return nextBtn
     }()
 
-    lazy var bottomView: UIView = {
+    public lazy var bottomView: UIView = {
         let bottomView = UIView(frame: CGRect(x: 0, y: cDefaultMargin * 2, width: cScreenWidth, height: cDevice_iPhoneNavBarHei))
         bottomView.addSubview(selecteBtn)
         bottomView.backgroundColor = BFConfig.shared.styleBackGroundColor
@@ -290,7 +344,7 @@ class PQUploadController: BFBaseViewController {
         return bottomView
     }()
 
-    override func viewDidLoad() {
+    override open func viewDidLoad() {
         super.viewDidLoad()
      
         view.backgroundColor =  BFConfig.shared.editCoverimageSelectedbackgroundColor
@@ -306,28 +360,29 @@ class PQUploadController: BFBaseViewController {
         //        PHPhotoLibrary.shared().unregisterChangeObserver(self)
     }
 
-    override func viewDidDisappear(_ animated: Bool) {
+    override open func viewDidDisappear(_ animated: Bool) {
         super.viewDidDisappear(animated)
   
     }
 
-    override func viewWillAppear(_ animated: Bool) {
+    override open func viewWillAppear(_ animated: Bool) {
         super.viewDidAppear(animated)
    
         addPlayerItemObserver()
     }
-    override func viewWillDisappear(_ animated: Bool) {
+    override open func viewWillDisappear(_ animated: Bool) {
         super.viewWillDisappear(animated)
         removePlayerItemObserver()
     }
-    func addSubViews() {
+    
+    open func addSubViews() {
         view.addSubview(collectionView)
         navHeadImageView?.addSubview(bottomView)
     
         PQNotification.addObserver(self, selector: #selector(didBecomeActiveNotification), name: UIApplication.didBecomeActiveNotification, object: nil)
     }
 
-    func loadLocalData() {
+    open func loadLocalData() {
         let authStatus = PHPhotoLibrary.authorizationStatus()
         if authStatus == .notDetermined {
             // 第一次触发授权 alert
@@ -372,7 +427,7 @@ class PQUploadController: BFBaseViewController {
         }
     }
 
-    func loadPhotoData() {
+    open func loadPhotoData() {
         DispatchQueue.main.async { [weak self] in
             BFLoadingHUB.shared.showHUB(superView: self!.view, isVerticality: false)
         }
@@ -422,7 +477,7 @@ class PQUploadController: BFBaseViewController {
     }
 
     // 转化处理获取到的相簿
-    func convertCollection(collection: PHAssetCollection?) {
+    open func convertCollection(collection: PHAssetCollection?) {
         if collection == nil {
             return
         }
@@ -440,7 +495,7 @@ class PQUploadController: BFBaseViewController {
         }
     }
 
-    @objc func btnClick(sender: UIButton) {
+    @objc open func btnClick(sender: UIButton) {
         switch sender.tag {
         case 1: // 返回
             navigationController?.popViewController(animated: true)
@@ -503,8 +558,9 @@ class PQUploadController: BFBaseViewController {
         }
     }
 
- 
- 
+    @objc func sliderValueDidChanged(sender: UISlider) {
+        avPlayer.seek(to: CMTime(value: CMTimeValue(sender.value * Float(CMTimeGetSeconds(avPlayer.currentItem?.duration ?? CMTime.zero))), timescale: 1))
+    }
 
     @objc func didBecomeActiveNotification() {
         if isJumpToAuthorization {
@@ -516,14 +572,14 @@ class PQUploadController: BFBaseViewController {
 }
 
 extension PQUploadController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, UIScrollViewDelegate {
-    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection _: Int) -> Int {
+    public 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 {
+    public 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 {
@@ -583,7 +639,7 @@ extension PQUploadController: UICollectionViewDelegate, UICollectionViewDataSour
         }
     }
 
-    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
+    public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
         if collectionView == self.collectionView {
             if videoData.count <= indexPath.item {
                 return
@@ -637,28 +693,28 @@ extension PQUploadController: UICollectionViewDelegate, UICollectionViewDataSour
         }
     }
 
-    func collectionView(_ collectionView: UICollectionView, layout _: UICollectionViewLayout, sizeForItemAt _: IndexPath) -> CGSize {
+    public 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 {
+    public 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 {
+    public func collectionView(_ collectionView: UICollectionView, layout _: UICollectionViewLayout, minimumInteritemSpacingForSectionAt _: Int) -> CGFloat {
         if collectionView == self.collectionView {
             return cDefaultMargin / 2
         }
         return 0
     }
 
-    func scrollViewDidScroll(_ scrollView: UIScrollView) {
+    public func scrollViewDidScroll(_ scrollView: UIScrollView) {
         //这里是不是有用的?
 //        if currentController() is PQUploadController || currentController() is PQImageSelectedController {
 //            if scrollView == collectionView {
@@ -674,7 +730,7 @@ extension PQUploadController: UICollectionViewDelegate, UICollectionViewDataSour
 }
 
 extension PQUploadController: PHPhotoLibraryChangeObserver {
-    func photoLibraryDidChange(_ changeInstance: PHChange) {
+    public 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
@@ -701,7 +757,7 @@ extension PQUploadController {
         playerItem?.removeObserver(self, forKeyPath: "status")
     }
 
-    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change _: [NSKeyValueChangeKey: Any]?, context _: UnsafeMutableRawPointer?) {
+    override public 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)")
             BFLoadingHUB.shared.dismissHUB(superView: playerHeaderView)