From ee4b05d4d779659f0ffa83deee7b6775a08c78d1 Mon Sep 17 00:00:00 2001 From: longitachi Date: Thu, 29 Oct 2020 18:37:14 +0800 Subject: [PATCH] release 4.0.9 --- Example/Example/ViewController.swift | 20 ++++++- LICENSE | 1 + README.md | 14 ++++- README_CN.md | 5 +- Sources/General/ZLEmbedAlbumListView.swift | 59 +++++++++++-------- Sources/General/ZLPhotoBrowser.swift | 2 +- Sources/General/ZLPhotoConfiguration.swift | 4 +- Sources/General/ZLPhotoManager.swift | 32 ++++------ Sources/General/ZLPhotoModel.swift | 2 +- Sources/General/ZLPhotoPreviewSheet.swift | 25 ++++---- .../General/ZLThumbnailViewController.swift | 9 ++- Sources/General/ZLVideoManager.swift | 8 +-- UPDATELOG.md | 14 +++++ ZLPhotoBrowser.podspec | 2 +- 14 files changed, 122 insertions(+), 75 deletions(-) diff --git a/Example/Example/ViewController.swift b/Example/Example/ViewController.swift index 60e4db0a..ab119e8d 100644 --- a/Example/Example/ViewController.swift +++ b/Example/Example/ViewController.swift @@ -122,7 +122,6 @@ class ViewController: UIViewController { } @objc func previewSelectPhoto() { -// ZLPhotoConfiguration.default().editImageClipRatios = [.custom, .wh1x1, .wh3x4, .wh16x9, ZLImageClipRatio(title: "2 : 1", whRatio: 2 / 1)] let ac = ZLPhotoPreviewSheet(selectedAssets: self.takeSelectedAssetsSwitch.isOn ? self.selectedAssets : []) ac.selectImageBlock = { [weak self] (images, assets, isOriginal) in self?.selectedImages = images @@ -131,12 +130,24 @@ class ViewController: UIViewController { self?.collectionView.reloadData() debugPrint("\(images) \(assets) \(isOriginal)") } + ac.cancelBlock = { + debugPrint("cancel select") + } + ac.selectImageRequestErrorBlock = { (errorAssets, errorIndexs) in + debugPrint("fetch error assets: \(errorAssets), error indexs: \(errorIndexs)") + } ac.showPreview(animate: true, sender: self) } @objc func librarySelectPhoto() { // ZLPhotoConfiguration.default().editImageClipRatios = [.custom, .wh1x1, .wh3x4, .wh16x9, ZLImageClipRatio(title: "2 : 1", whRatio: 2 / 1)] // ZLPhotoConfiguration.default().filters = [.normal, .process, ZLFilter(name: "custom", applier: ZLCustomFilter.hazeRemovalFilter)] + + // You can first determine whether the asset is allowed to be selected. + ZLPhotoConfiguration.default().canSelectAsset = { (asset) -> Bool in + return true + } + let ac = ZLPhotoPreviewSheet(selectedAssets: self.takeSelectedAssetsSwitch.isOn ? self.selectedAssets : []) ac.selectImageBlock = { [weak self] (images, assets, isOriginal) in self?.selectedImages = images @@ -144,6 +155,12 @@ class ViewController: UIViewController { self?.collectionView.reloadData() debugPrint("\(images) \(assets) \(isOriginal)") } + ac.cancelBlock = { + debugPrint("cancel select") + } + ac.selectImageRequestErrorBlock = { (errorAssets, errorIndexs) in + debugPrint("fetch error assets: \(errorAssets), error indexs: \(errorIndexs)") + } ac.showPhotoLibrary(sender: self) } @@ -171,6 +188,7 @@ class ViewController: UIViewController { let videoSuffixs = ["mp4", "mov", "avi", "rmvb", "rm", "flv", "3gp", "wmv", "vob", "dat", "m4v", "f4v", "mkv"] // and more suffixs let vc = ZLImagePreviewController(datas: datas, index: 0, showSelectBtn: true) { (url) -> ZLURLType in + // Just for demo. if url.absoluteString == netVideoUrlString { return .video } diff --git a/LICENSE b/LICENSE index 16cb04e4..328e499d 100644 --- a/LICENSE +++ b/LICENSE @@ -19,3 +19,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/README.md b/README.md index f15b8158..c02e4366 100644 --- a/README.md +++ b/README.md @@ -89,9 +89,17 @@ Detailed usage of `Swift` and `OC`, please refer to [Wiki](https://github.com/lo ### Update Log > [More logs](https://github.com/longitachi/ZLPhotoBrowser/blob/master/UPDATELOG.md) ``` -● 4.0.8: Add filter to image editor; -● 4.0.7: Image editor support crop ratios; Custom camera supports switching camera during recording; bug fixed; -● 4.0.5: Support iOS14 limited authority; Optimize picture preview display; +● 4.0.9: + Support languages of more countries (French, German, Russian, Vietnamese, Korean, Malay, Italian). + Support iOS14 limited authority. + Provides the ability to preview PHAsset, local images and videos, network images and videos together. + Optimize some UI effects. +● 4.0.8: + Add filter to image editor. +● 4.0.7: + Image editor support crop ratios. + Custom camera supports switching camera during recording. + bug fixed. ... ``` diff --git a/README_CN.md b/README_CN.md index 73786b7c..30f27f43 100644 --- a/README_CN.md +++ b/README_CN.md @@ -96,13 +96,10 @@ ### 更新日志 > [更多更新日志](https://github.com/longitachi/ZLPhotoBrowser/blob/master/UPDATELOG.md) ``` +● 4.0.9: 支持更多国家的语言; 完善iOS14 limited authority 权限的适配; 提供可以同时预览PHAsset、本地图片/视频及网络图片/视频的功能; 优化部分UI效果; ● 4.0.8: 编辑图片添加滤镜功能; ● 4.0.7: 支持设置图片裁剪比例; 自定义相机支持录制时切换摄像头; 新增已选照片边框功能; 新增是否允许预览大图功能;其他细节优化及已知bug修复; ● 4.0.5: 适配iOS14 limited权限; 优化图片预览显示; 优化大长/宽图编辑; -● 4.0.4: 优化图片编辑体验,记录之前编辑状态; 添加是否允许拍照参数; 优化降序照片获取顺序; fix #510, fix #513; 修复其他已知bug; -● 4.0.2: 新增框架样式设置(新增一种仿微信的样式); 编辑图片添加马赛克功能; 添加下拉返回动画; 自定义相机支持最短录制时间设置; 优化gif照片的回调; -● 4.0.1: 优化视频编辑功能; 增加自定义列数功能; 修复一些bug; -● 4.0.0: 框架升级为纯`Swift`编写,最低支持右`iOS8`升级到`iOS10`; ... ``` diff --git a/Sources/General/ZLEmbedAlbumListView.swift b/Sources/General/ZLEmbedAlbumListView.swift index 1fdcca78..2cd408ab 100644 --- a/Sources/General/ZLEmbedAlbumListView.swift +++ b/Sources/General/ZLEmbedAlbumListView.swift @@ -25,6 +25,7 @@ // THE SOFTWARE. import UIKit +import Photos class ZLEmbedAlbumListView: UIView { @@ -105,13 +106,14 @@ class ZLEmbedAlbumListView: UIView { self.addGestureRecognizer(tap) } - func loadAlbumList() { + func loadAlbumList(completion: ( () -> Void )? = nil) { DispatchQueue.global().async { ZLPhotoManager.getPhotoAlbumList(ascending: ZLPhotoConfiguration.default().sortAscending, allowSelectImage: ZLPhotoConfiguration.default().allowSelectImage, allowSelectVideo: ZLPhotoConfiguration.default().allowSelectVideo) { [weak self] (albumList) in self?.arrDataSource.removeAll() self?.arrDataSource.append(contentsOf: albumList) DispatchQueue.main.async { + completion?() self?.tableView.reloadData() } } @@ -133,30 +135,41 @@ class ZLEmbedAlbumListView: UIView { /// 这里不采用监听相册发生变化的方式,是因为每次变化,系统都会回调多次,造成重复获取相册列表 func show(reloadAlbumList: Bool) { - if reloadAlbumList { - self.loadAlbumList() - } - - let toFrame = self.calculateBgViewBounds() - - self.isHidden = false - self.alpha = 0 - var newFrame = toFrame - newFrame.origin.y -= newFrame.height - - if newFrame != self.tableBgView.frame { - let path = UIBezierPath(roundedRect: CGRect(x: 0, y: 0, width: newFrame.width, height: newFrame.height), byRoundingCorners: [.bottomLeft, .bottomRight], cornerRadii: CGSize(width: 8, height: 8)) - self.tableBgView.layer.mask = nil - let maskLayer = CAShapeLayer() - maskLayer.path = path.cgPath - self.tableBgView.layer.mask = maskLayer + func animateShow() { + let toFrame = self.calculateBgViewBounds() + + self.isHidden = false + self.alpha = 0 + var newFrame = toFrame + newFrame.origin.y -= newFrame.height + + if newFrame != self.tableBgView.frame { + let path = UIBezierPath(roundedRect: CGRect(x: 0, y: 0, width: newFrame.width, height: newFrame.height), byRoundingCorners: [.bottomLeft, .bottomRight], cornerRadii: CGSize(width: 8, height: 8)) + self.tableBgView.layer.mask = nil + let maskLayer = CAShapeLayer() + maskLayer.path = path.cgPath + self.tableBgView.layer.mask = maskLayer + } + + self.tableBgView.frame = newFrame + self.tableView.frame = self.tableBgView.bounds + UIView.animate(withDuration: 0.25) { + self.alpha = 1 + self.tableBgView.frame = toFrame + } } - self.tableBgView.frame = newFrame - self.tableView.frame = self.tableBgView.bounds - UIView.animate(withDuration: 0.25) { - self.alpha = 1 - self.tableBgView.frame = toFrame + if reloadAlbumList { + if #available(iOS 14.0, *), PHPhotoLibrary.authorizationStatus(for: .readWrite) == .limited { + self.loadAlbumList { + animateShow() + } + } else { + self.loadAlbumList() + animateShow() + } + } else { + animateShow() } } diff --git a/Sources/General/ZLPhotoBrowser.swift b/Sources/General/ZLPhotoBrowser.swift index 83c71b24..80e446f6 100644 --- a/Sources/General/ZLPhotoBrowser.swift +++ b/Sources/General/ZLPhotoBrowser.swift @@ -24,4 +24,4 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -let version = "4.0.8" +let version = "4.0.9" diff --git a/Sources/General/ZLPhotoConfiguration.swift b/Sources/General/ZLPhotoConfiguration.swift index c0667ab3..258e227d 100644 --- a/Sources/General/ZLPhotoConfiguration.swift +++ b/Sources/General/ZLPhotoConfiguration.swift @@ -215,7 +215,7 @@ public class ZLPhotoConfiguration: NSObject { /// Show the image captured by the camera is displayed on the camera button inside the album. @objc public var showCaptureImageOnTakePhotoBtn = false - /// In the control single-selection mode, whether to display the selection button, the multi-selection mode is not controlled. + /// In single selection mode, whether to display the selection button. @objc public var showSelectBtnWhenSingleSelect = false /// Overlay a mask layer on top of the selected photos. @@ -233,7 +233,7 @@ public class ZLPhotoConfiguration: NSObject { /// Display the selected photos at the bottom of the preview large photos interface. @objc public var showSelectedPhotoPreview = true - /// Developers can customize pictures, but the name of the custom picture resource must be consistent with the picture name in the replaced bundle. + /// Developers can customize iamges, but the name of the custom image resource must be consistent with the image name in the replaced bundle. /// - example: Developers need to replace the selected and unselected image resources, and the array that needs to be passed in is /// ["zl_btn_selected", "zl_btn_unselected"]. @objc public var customImageNames: [String] = [] { diff --git a/Sources/General/ZLPhotoManager.swift b/Sources/General/ZLPhotoManager.swift index c7599329..ed137ab1 100644 --- a/Sources/General/ZLPhotoManager.swift +++ b/Sources/General/ZLPhotoManager.swift @@ -29,7 +29,7 @@ import Photos public class ZLPhotoManager: NSObject { - /// save image to album + /// Save image to album. @objc public class func saveImageToAlbum(image: UIImage, completion: ( (Bool, PHAsset?) -> Void )? ) { let status = PHPhotoLibrary.authorizationStatus() @@ -54,7 +54,7 @@ public class ZLPhotoManager: NSObject { } } - /// save video to album + /// Save video to album. @objc public class func saveVideoToAlbum(url: URL, completion: ( (Bool, PHAsset?) -> Void )? ) { let status = PHPhotoLibrary.authorizationStatus() @@ -90,7 +90,7 @@ public class ZLPhotoManager: NSObject { return nil } - /// fetch photos from result + /// Fetch photos from result. class func fetchPhoto(in result: PHFetchResult, ascending: Bool, allowSelectImage: Bool, allowSelectVideo: Bool, limitCount: Int = .max) -> [ZLPhotoModel] { var models: [ZLPhotoModel] = [] let option: NSEnumerationOptions = ascending ? .init(rawValue: 0) : .reverse @@ -116,7 +116,7 @@ public class ZLPhotoManager: NSObject { return models } - /// fetch all album list + /// Fetch all album list. class func getPhotoAlbumList(ascending: Bool, allowSelectImage: Bool, allowSelectVideo: Bool, completion: ( ([ZLAlbumListModel]) -> Void )) { let option = PHFetchOptions() if !allowSelectImage { @@ -150,7 +150,7 @@ public class ZLPhotoManager: NSObject { let title = self.getCollectionTitle(collection) if collection.assetCollectionSubtype == .smartAlbumUserLibrary { - // 所有照片 + // Album of all photos. let m = ZLAlbumListModel(title: title, result: result, collection: collection, option: option, isCameraRoll: true) albumList.insert(m, at: 0) } else { @@ -163,7 +163,7 @@ public class ZLPhotoManager: NSObject { completion(albumList) } - /// fetch camera roll album + /// Fetch camera roll album. class func getCameraRollAlbum(allowSelectImage: Bool, allowSelectVideo: Bool, completion: @escaping ( (ZLAlbumListModel) -> Void )) { let option = PHFetchOptions() if !allowSelectImage { @@ -184,10 +184,10 @@ public class ZLPhotoManager: NSObject { } } - /// conversion collection title + /// Conversion collection title. private class func getCollectionTitle(_ collection: PHAssetCollection) -> String { if collection.assetCollectionType == .album { - // 用户创建的相册 + // Albums created by user. var title: String? = nil if ZLCustomLanguageDeploy.language == .system { title = collection.localizedTitle @@ -255,7 +255,7 @@ public class ZLPhotoManager: NSObject { return self.fetchImage(for: asset, size: PHImageManagerMaximumSize, resizeMode: .fast, progress: progress, completion: completion) } - /// fetch asset data + /// Fetch asset data. @discardableResult class func fetchOriginalImageData(for asset: PHAsset, progress: ( (CGFloat, Error?, UnsafeMutablePointer, [AnyHashable : Any]?) -> Void )? = nil, completion: @escaping ( (Data, [AnyHashable: Any]?, Bool) -> Void)) -> PHImageRequestID { let option = PHImageRequestOptions() @@ -280,14 +280,9 @@ public class ZLPhotoManager: NSObject { } } - /// fetch image for asset + /// Fetch image for asset. private class func fetchImage(for asset: PHAsset, size: CGSize, resizeMode: PHImageRequestOptionsResizeMode, progress: ( (CGFloat, Error?, UnsafeMutablePointer, [AnyHashable : Any]?) -> Void )? = nil, completion: @escaping ( (UIImage?, Bool) -> Void )) -> PHImageRequestID { let option = PHImageRequestOptions() - /** - resizeMode:对请求的图像怎样缩放。有三种选择:None,默认加载方式;Fast,尽快地提供接近或稍微大于要求的尺寸;Exact,精准提供要求的尺寸。 - deliveryMode:图像质量。有三种值:Opportunistic,在速度与质量中均衡;HighQualityFormat,不管花费多长时间,提供高质量图像;FastFormat,以最快速度提供好的质量。 - 这个属性只有在 synchronous 为 true 时有效。 - */ option.resizeMode = resizeMode option.isNetworkAccessAllowed = true option.progressHandler = { (pro, error, stop, info) in @@ -306,7 +301,6 @@ public class ZLPhotoManager: NSObject { completion(image, isDegraded) } } - } class func fetchLivePhoto(for asset: PHAsset, completion: @escaping ( (PHLivePhoto?, [AnyHashable: Any]?, Bool) -> Void )) -> PHImageRequestID { @@ -330,7 +324,7 @@ public class ZLPhotoManager: NSObject { } } return PHImageManager.default().requestPlayerItem(forVideo: asset, options: option) { (item, info) in - // iOS11 系统这个回调没有在主线程 + // iOS11 and earlier, callback is not on the main thread. DispatchQueue.main.async { let isDegraded = (info?[PHImageResultIsDegradedKey] as? Bool ?? false) completion(item, info, isDegraded) @@ -360,7 +354,7 @@ public class ZLPhotoManager: NSObject { } } - /// fetch asset local file path + /// Fetch asset local file path. @objc public class func fetchAssetFilePath(asset: PHAsset, completion: @escaping (String?) -> Void ) { asset.requestContentEditingInput(with: nil) { (input, info) in var path = input?.fullSizeImageURL?.absoluteString @@ -374,7 +368,7 @@ public class ZLPhotoManager: NSObject { } -/// authority related +/// Authority related. extension ZLPhotoManager { public class func havePhotoLibratyAuthority() -> Bool { diff --git a/Sources/General/ZLPhotoModel.swift b/Sources/General/ZLPhotoModel.swift index 425e75c1..0decad7f 100644 --- a/Sources/General/ZLPhotoModel.swift +++ b/Sources/General/ZLPhotoModel.swift @@ -78,7 +78,7 @@ class ZLPhotoModel: NSObject { } } - // 保存上次编辑图片的一些内容,下次编辑时候可继续上次的编辑 + // Content of the last edit. var editImageModel: ZLEditImageModel? init(asset: PHAsset) { diff --git a/Sources/General/ZLPhotoPreviewSheet.swift b/Sources/General/ZLPhotoPreviewSheet.swift index 72725be8..9b3760ed 100644 --- a/Sources/General/ZLPhotoPreviewSheet.swift +++ b/Sources/General/ZLPhotoPreviewSheet.swift @@ -105,17 +105,10 @@ public class ZLPhotoPreviewSheet: UIView { if !ZLPhotoConfiguration.default().allowSelectImage && !ZLPhotoConfiguration.default().allowSelectVideo { - assert(false, "参数配置错误") + assert(false, "ZLPhotoBrowser: error configuration") ZLPhotoConfiguration.default().allowSelectImage = true } - let models = selectedAssets.map { (asset) -> ZLPhotoModel in - let m = ZLPhotoModel(asset: asset) - m.isSelected = true - return m - } - self.arrSelectedModels.append(contentsOf: models) - self.fetchImageQueue.maxConcurrentOperationCount = 3 self.setupUI() @@ -304,7 +297,7 @@ public class ZLPhotoPreviewSheet: UIView { } } - // 状态为limit时候注册相册变化通知,由于photoLibraryDidChange方法会在每次相册变化时候回调多次,导致界面多次刷新,所以其他情况不监听相册变化 + // Register for the album change notification when the status is limited, because the photoLibraryDidChange method will be repeated multiple times each time the album changes, causing the interface to refresh multiple times. So the album changes are not monitored in other authority. if #available(iOS 14.0, *), preview, PHPhotoLibrary.authorizationStatus(for: .readWrite) == .limited { PHPhotoLibrary.shared().register(self) } @@ -352,7 +345,6 @@ public class ZLPhotoPreviewSheet: UIView { func hide() { if self.animate { - var frame = self.baseView.frame frame.origin.y += self.baseViewHeight UIView.animate(withDuration: 0.2, animations: { @@ -379,6 +371,7 @@ public class ZLPhotoPreviewSheet: UIView { } if !self.baseView.frame.contains(location) { + self.cancelBlock?() self.hide() } } @@ -449,7 +442,6 @@ public class ZLPhotoPreviewSheet: UIView { } if self.panImageView == nil { - // 必须向上拖动 guard point.y < self.panBeginPoint.y else { return } @@ -543,11 +535,11 @@ public class ZLPhotoPreviewSheet: UIView { if let image = image { images[i] = image assets[i] = asset ?? m.asset - zl_debugPrint("---- suc request \(i)") + zl_debugPrint("ZLPhotoBrowser: suc request \(i)") } else { errorAssets[i] = m.asset errorIndexs[i] = i - zl_debugPrint("---- failed request \(i)") + zl_debugPrint("ZLPhotoBrowser: failed request \(i)") } guard sucCount >= totalCount else { return } @@ -714,7 +706,12 @@ public class ZLPhotoPreviewSheet: UIView { func handleDataArray(newModel: ZLPhotoModel) { self.arrDataSources.insert(newModel, at: 0) - if canAddModel(newModel, currentSelectCount: self.arrSelectedModels.count, sender: self.sender, showAlert: false) { + var canSelect = true + // If mixed selection is not allowed, and the newModel type is video, it will not be selected. + if !ZLPhotoConfiguration.default().allowMixSelect, newModel.type == .video { + canSelect = false + } + if canSelect, canAddModel(newModel, currentSelectCount: self.arrSelectedModels.count, sender: self.sender, showAlert: false) { if !self.shouldDirectEdit(newModel) { newModel.isSelected = true self.arrSelectedModels.append(newModel) diff --git a/Sources/General/ZLThumbnailViewController.swift b/Sources/General/ZLThumbnailViewController.swift index 84a1ec09..dcdaefd7 100644 --- a/Sources/General/ZLThumbnailViewController.swift +++ b/Sources/General/ZLThumbnailViewController.swift @@ -141,7 +141,7 @@ class ZLThumbnailViewController: UIViewController { self.loadPhotos() - // 状态为limit时候注册相册变化通知,由于photoLibraryDidChange方法会在每次相册变化时候回调多次,导致界面多次刷新,所以其他情况不监听相册变化 + // Register for the album change notification when the status is limited, because the photoLibraryDidChange method will be repeated multiple times each time the album changes, causing the interface to refresh multiple times. So the album changes are not monitored in other authority. if #available(iOS 14.0, *), PHPhotoLibrary.authorizationStatus(for: .readWrite) == .limited { PHPhotoLibrary.shared().register(self) } @@ -609,7 +609,12 @@ class ZLThumbnailViewController: UIViewController { self.arrDataSources.insert(newModel, at: 0) } - if canAddModel(newModel, currentSelectCount: nav?.arrSelectedModels.count ?? 0, sender: self, showAlert: false) { + var canSelect = true + // If mixed selection is not allowed, and the newModel type is video, it will not be selected. + if !config.allowMixSelect, newModel.type == .video { + canSelect = false + } + if canSelect, canAddModel(newModel, currentSelectCount: nav?.arrSelectedModels.count ?? 0, sender: self, showAlert: false) { if !self.shouldDirectEdit(newModel) { newModel.isSelected = true nav?.arrSelectedModels.append(newModel) diff --git a/Sources/General/ZLVideoManager.swift b/Sources/General/ZLVideoManager.swift index a08e76c7..e707444e 100644 --- a/Sources/General/ZLVideoManager.swift +++ b/Sources/General/ZLVideoManager.swift @@ -37,7 +37,7 @@ public class ZLVideoManager: NSObject { @objc public class func exportEditVideo(for asset: AVAsset, range: CMTimeRange, completion: @escaping ( (URL?, Error?) -> Void )) { let outputUrl = URL(fileURLWithPath: self.getVideoExportFilePath()) guard let exportSession = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetPassthrough) else { - completion(nil, NSError(domain: "", code: -1000, userInfo: [NSLocalizedDescriptionKey: "export video failed"])) + completion(nil, NSError(domain: "", code: -1000, userInfo: [NSLocalizedDescriptionKey: "video export failed"])) return } exportSession.outputURL = outputUrl @@ -47,7 +47,7 @@ public class ZLVideoManager: NSObject { exportSession.exportAsynchronously(completionHandler: { let suc = exportSession.status == .completed if exportSession.status == .failed { - zl_debugPrint("导出视频失败 \(exportSession.error?.localizedDescription ?? "")") + zl_debugPrint("ZLPhotoBrowser: video export failed: \(exportSession.error?.localizedDescription ?? "")") } DispatchQueue.main.async { completion(suc ? outputUrl : nil, exportSession.error) @@ -109,7 +109,7 @@ public class ZLVideoManager: NSObject { } guard let exportSession = AVAssetExportSession(asset: mixComposition, presetName: AVAssetExportPreset1280x720) else { - completion(nil, NSError(domain: "", code: -1000, userInfo: [NSLocalizedDescriptionKey: "merge video failed"])) + completion(nil, NSError(domain: "", code: -1000, userInfo: [NSLocalizedDescriptionKey: "video merge failed"])) return } @@ -121,7 +121,7 @@ public class ZLVideoManager: NSObject { exportSession.exportAsynchronously(completionHandler: { let suc = exportSession.status == .completed if exportSession.status == .failed { - zl_debugPrint("合并视频失败 \(exportSession.error?.localizedDescription ?? "")") + zl_debugPrint("ZLPhotoBrowser: video merge failed: \(exportSession.error?.localizedDescription ?? "")") } DispatchQueue.main.async { completion(suc ? outputUrl : nil, exportSession.error) diff --git a/UPDATELOG.md b/UPDATELOG.md index 7b07a5f4..0d85a67a 100755 --- a/UPDATELOG.md +++ b/UPDATELOG.md @@ -1,5 +1,19 @@ # Update Log +----- +## [4.0.9](https://github.com/longitachi/ZLPhotoBrowser/releases/tag/4.0.9) (2020-10-29) + +### Add +* Support languages of more countries (French, German, Russian, Vietnamese, Korean, Malay, Italian). +* Support iOS14 limited authority. +* Provides the ability to preview PHAsset, local images and videos, network images and videos together. +* Optimize some UI effects. + +### Fix +* Fixed the bug that the selected index is displayed in the video cell after recording the video.[#546](https://github.com/longitachi/ZLPhotoBrowser/issues/546) + +--- + ----- ## [4.0.8](https://github.com/longitachi/ZLPhotoBrowser/releases/tag/4.0.8) (2020-10-10) diff --git a/ZLPhotoBrowser.podspec b/ZLPhotoBrowser.podspec index 557d2da0..b61bc187 100644 --- a/ZLPhotoBrowser.podspec +++ b/ZLPhotoBrowser.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'ZLPhotoBrowser' - s.version = '4.0.8' + s.version = '4.0.9' s.summary = 'A lightweight and pure Swift implemented library for select photos from album' s.description = <<-DESC