diff --git a/Example/ExampleViewController.swift b/Example/ExampleViewController.swift
index 23e74becd..58b6f122e 100644
--- a/Example/ExampleViewController.swift
+++ b/Example/ExampleViewController.swift
@@ -89,6 +89,7 @@ class ExampleViewController: UIViewController {
/* Choose what media types are available in the library. Defaults to `.photo` */
config.library.mediaType = .photoAndVideo
config.library.itemOverlayType = .grid
+ config.library.sortingOption = .creationDate
/* Enables selecting the front camera by default, useful for avatars. Defaults to false */
// config.usesFrontCamera = true
@@ -133,6 +134,8 @@ class ExampleViewController: UIViewController {
/* Defines the time limit for videos from the library.
Defaults to 60 seconds. */
config.video.libraryTimeLimit = 500.0
+
+ config.video.compressionOption = [compressionOptions.AVAssetExportPreset640x480,compressionOptions.AVAssetExportPreset1920x1080, compressionOptions.AVAssetExportPresetPassthrough]
/* Adds a Crop step in the photo taking process, after filters. Defaults to .none */
config.showsCrop = .rectangle(ratio: (16/9))
diff --git a/Package.resolved b/Package.resolved
index 04d119d60..189a47d14 100644
--- a/Package.resolved
+++ b/Package.resolved
@@ -15,8 +15,8 @@
"repositoryURL": "https://github.com/freshOS/Stevia",
"state": {
"branch": null,
- "revision": "87dd17a86240f16788239a78dd8be11c4b013150",
- "version": "4.8.0"
+ "revision": "cfb1a1d2159277bb553c3dc46f3f742c0275566d",
+ "version": "5.1.2"
}
}
]
diff --git a/Source/Configuration/YPImagePickerConfiguration.swift b/Source/Configuration/YPImagePickerConfiguration.swift
index 5cb79e13b..f887bd660 100644
--- a/Source/Configuration/YPImagePickerConfiguration.swift
+++ b/Source/Configuration/YPImagePickerConfiguration.swift
@@ -115,6 +115,12 @@ public struct YPImagePickerConfiguration {
/// Defines the text colour to be shown when a bottom option is unselected
public var bottomMenuItemUnSelectedTextColour: UIColor = .ypSecondaryLabel
+ /// Defines the text colour to be shown for selectMoreButton
+ public var selectMoreButtonBackgroundColour: UIColor = .ypSystemBlue
+
+ /// Defines the text colour to be shown for seeAllPhotoButton
+ public var seeAllPhotosButtonBackgroundColour: UIColor = .ypSystemBlue
+
/// Defines the max camera zoom factor for camera. Disable camera zoom with 1. Default is 1.
public var maxCameraZoomFactor: CGFloat = 1.0
@@ -227,6 +233,9 @@ public struct YPConfigLibrary {
/// Set the overlay type shown on top of the selected library item
public var itemOverlayType: YPItemOverlayType = .grid
+
+ /// The library items are sorted by time created or modified
+ public var sortingOption: SortingOption = SortingOption.creationDate
}
/// Encapsulates video specific settings.
@@ -246,6 +255,9 @@ public struct YPConfigVideo {
*/
public var compression: String = AVAssetExportPresetHighestQuality
+ /// Choose the different video compression option to be supported
+ public var compressionOption: [compressionOptions] = [compressionOptions.AVAssetExportPresetPassthrough]
+
/// Choose the result video extension if you trim or compress a video. Defaults to mov.
public var fileType: AVFileType = .mov
@@ -304,3 +316,71 @@ public enum YPlibraryMediaType {
case video
case photoAndVideo
}
+
+public enum SortingOption: String {
+ case modificationDate = "modificationDate"
+ case creationDate = "creationDate"
+}
+
+public enum compressionOptions: String {
+ case AVAssetExportPresetLowQuality
+ case AVAssetExportPreset640x480
+ case AVAssetExportPresetMediumQuality
+ case AVAssetExportPreset1920x1080
+ case AVAssetExportPreset1280x720
+ case AVAssetExportPresetHighestQuality
+ case AVAssetExportPresetAppleM4A
+ case AVAssetExportPreset3840x2160
+ case AVAssetExportPreset960x540
+ case AVAssetExportPresetPassthrough
+
+ func presetID() -> String {
+ switch self {
+ case .AVAssetExportPresetLowQuality:
+ return "AVAssetExportPresetLowQuality"
+ case .AVAssetExportPreset640x480:
+ return "AVAssetExportPreset640x480"
+ case .AVAssetExportPresetMediumQuality:
+ return "AVAssetExportPresetMediumQuality"
+ case .AVAssetExportPreset1920x1080:
+ return "AVAssetExportPreset1920x1080"
+ case .AVAssetExportPreset1280x720:
+ return "AVAssetExportPreset1280x720"
+ case .AVAssetExportPresetHighestQuality:
+ return "AVAssetExportPresetHighestQuality"
+ case .AVAssetExportPresetAppleM4A:
+ return "AVAssetExportPresetAppleM4A"
+ case .AVAssetExportPreset3840x2160:
+ return "AVAssetExportPreset3840x2160"
+ case .AVAssetExportPreset960x540:
+ return "AVAssetExportPreset960x540"
+ case .AVAssetExportPresetPassthrough:
+ return "AVAssetExportPresetPassthrough"
+ }
+ }
+
+ func getLabel() -> String {
+ switch self {
+ case .AVAssetExportPresetLowQuality:
+ return YPConfig.wordings.textAVAssetExportPresetLowQuality
+ case .AVAssetExportPreset640x480:
+ return YPConfig.wordings.textAVAssetExportPreset640x480
+ case .AVAssetExportPresetMediumQuality:
+ return YPConfig.wordings.textAVAssetExportPresetMediumQuality
+ case .AVAssetExportPreset1920x1080:
+ return YPConfig.wordings.textAVAssetExportPreset1920x1080
+ case .AVAssetExportPreset1280x720:
+ return YPConfig.wordings.textAVAssetExportPreset1280x720
+ case .AVAssetExportPresetHighestQuality:
+ return YPConfig.wordings.textAVAssetExportPresetHighestQuality
+ case .AVAssetExportPresetAppleM4A:
+ return YPConfig.wordings.textAVAssetExportPresetAppleM4A
+ case .AVAssetExportPreset3840x2160:
+ return YPConfig.wordings.textAVAssetExportPreset3840x2160
+ case .AVAssetExportPreset960x540:
+ return YPConfig.wordings.textAVAssetExportPreset960x540
+ case .AVAssetExportPresetPassthrough:
+ return YPConfig.wordings.textAVAssetExportPresetPassthrough
+ }
+ }
+}
diff --git a/Source/Configuration/YPWordings.swift b/Source/Configuration/YPWordings.swift
index 2a4288961..eb01f614c 100644
--- a/Source/Configuration/YPWordings.swift
+++ b/Source/Configuration/YPWordings.swift
@@ -41,4 +41,15 @@ public struct YPWordings {
public var filter = ypLocalized("YPImagePickerFilter")
public var crop = ypLocalized("YPImagePickerCrop")
public var warningMaxItemsLimit = ypLocalized("YPImagePickerWarningItemsLimit")
+
+ public var textAVAssetExportPresetLowQuality = ypLocalized("Low")
+ public var textAVAssetExportPreset640x480 = ypLocalized("Medium (HD)")
+ public var textAVAssetExportPresetMediumQuality = ypLocalized("Medium")
+ public var textAVAssetExportPreset1920x1080 = ypLocalized("High (Full HD)")
+ public var textAVAssetExportPreset1280x720 = ypLocalized("1280 x 720")
+ public var textAVAssetExportPresetHighestQuality = ypLocalized("Highest")
+ public var textAVAssetExportPresetAppleM4A = ypLocalized("Apple M4A")
+ public var textAVAssetExportPreset3840x2160 = ypLocalized("3840 x 2160")
+ public var textAVAssetExportPreset960x540 = ypLocalized("960 x 540")
+ public var textAVAssetExportPresetPassthrough = ypLocalized("Original")
}
diff --git a/Source/Filters/Video/YPVideoCompressionVC.storyboard b/Source/Filters/Video/YPVideoCompressionVC.storyboard
new file mode 100644
index 000000000..f84dc2f19
--- /dev/null
+++ b/Source/Filters/Video/YPVideoCompressionVC.storyboard
@@ -0,0 +1,144 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source/Filters/Video/YPVideoCompressionVC.swift b/Source/Filters/Video/YPVideoCompressionVC.swift
new file mode 100644
index 000000000..7aeecb9b0
--- /dev/null
+++ b/Source/Filters/Video/YPVideoCompressionVC.swift
@@ -0,0 +1,149 @@
+//
+// YPVideoCompressionVC.swift
+// YPImagePicker
+//
+// Created by Nirai on 10/10/22.
+// Copyright © 2022 Yummypets. All rights reserved.
+//
+
+import UIKit
+
+let COMPRESSION_OPTION = "YPCompressionOption"
+
+class YPVideoCompressionVC: UIViewController, UITableViewDelegate, UITableViewDataSource {
+
+ @IBOutlet weak var tableView: UITableView!
+ @IBOutlet weak var bkgOverlayView: UIView!
+
+ @IBOutlet weak var tableViewHeightConstraint: NSLayoutConstraint!
+
+ var titleArray = [String]()
+ var checkedIndex: Int? = nil
+ var headingTitle: String = ""
+
+ var didDismiss: (Int) -> Void = { (index: Int) in
+ }
+
+ required init() {
+ super.init(nibName: nil, bundle: nil)
+ }
+
+ required init?(coder: NSCoder) {
+ super.init(coder: coder)
+ }
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ //keep original as default vide compression option
+ self.checkedIndex = (UserDefaults.standard.object(forKey: COMPRESSION_OPTION) != nil) ? UserDefaults.standard.integer(forKey: COMPRESSION_OPTION) : (titleArray.count - 1)
+
+ self.bkgOverlayView.alpha = 0.2
+ self.presentAnimateTransition()
+ self.setTableViewHeight()
+ self.tableView.layer.cornerRadius = 8.0
+ if #available(iOS 15.0, *) {
+ UITableView.appearance().sectionHeaderTopPadding = 0.0
+ }
+ }
+
+ override func viewDidAppear(_ animated: Bool) {
+ super.viewDidAppear(animated)
+ //StatusBar.statusBar.customizeStatusBar(.Translucent(0.2))
+ }
+
+ override func viewWillAppear(_ animated: Bool) {
+ super.viewWillAppear(animated)
+ }
+
+ override func viewDidDisappear(_ animated: Bool) {
+ super.viewDidDisappear(animated)
+ //StatusBar.statusBar.customizeStatusBar(.Default)
+ }
+
+ func setTableViewHeight() {
+ tableViewHeightConstraint.constant = CGFloat((titleArray.count + 1) * 44)
+ }
+
+ func presentAnimateTransition() {
+ tableView.center = self.view.center
+ tableView.transform = CGAffineTransform.init(scaleX: 0.4, y: 0.4)
+ tableView.alpha = 0
+ UIView.animate(withDuration: 0.33) {
+ self.tableView.alpha = 1
+ self.tableView.transform = CGAffineTransform.identity
+ }
+ }
+
+ @IBAction func overlayViewTapped(_ tapGesture: UITapGestureRecognizer) {
+ //ITALogger.log.debug("check mark overview pressed")
+ //AnalyticsManager.manager.logNewEvent(category: "check_mark_view", action: "card_settings_sheet_dismiss", label: "card setting sheet dismiss", value: nil)
+ //keep original as default vide compression option
+ self.didDismiss(self.checkedIndex ?? (titleArray.count - 1))
+ self.dismiss(animated: true, completion: nil)
+ }
+
+ func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+ return titleArray.count
+ }
+
+ func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
+ return 44.0
+ }
+
+ func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
+ let headerCell = tableView.dequeueReusableCell(withIdentifier: "HeaderCell") as! HeaderCell
+ headerCell.title.text = headingTitle
+ return headerCell
+ }
+
+ func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
+ return 44.0
+ }
+
+ func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
+ let cell = tableView.dequeueReusableCell(withIdentifier: "CompressionOptionCell") as! CompressionOptionCell
+ cell.separatorInset = .zero
+ cell.configure(titleString: titleArray[indexPath.row])
+ if indexPath.row == self.checkedIndex {
+ cell.setChecked()
+ }
+ return cell
+ }
+
+
+ func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
+ self.checkedIndex = indexPath.row
+ UserDefaults.standard.set(self.checkedIndex, forKey: COMPRESSION_OPTION)
+ //keep original as default vide compression option
+ self.didDismiss(self.checkedIndex ?? (titleArray.count - 1))
+ self.dismiss(animated: true, completion: nil)
+ }
+
+ override func didReceiveMemoryWarning() {
+ super.didReceiveMemoryWarning()
+ }
+
+}
+
+class CompressionOptionCell: UITableViewCell {
+ @IBOutlet weak var tickMark: UIImageView!
+ @IBOutlet weak var title: UILabel!
+
+ func configure(titleString: String) {
+ self.setUnchecked()
+ self.title.text = titleString
+ }
+
+ func setChecked() {
+ self.tickMark.isHidden = false
+ }
+
+ func setUnchecked() {
+ self.tickMark.isHidden = true
+ }
+}
+
+class HeaderCell: UITableViewCell {
+ @IBOutlet weak var title: UILabel!
+}
diff --git a/Source/Filters/Video/YPVideoFiltersVC.swift b/Source/Filters/Video/YPVideoFiltersVC.swift
index 2e2c8e3a9..cdc4eb7b5 100644
--- a/Source/Filters/Video/YPVideoFiltersVC.swift
+++ b/Source/Filters/Video/YPVideoFiltersVC.swift
@@ -200,7 +200,7 @@ public final class YPVideoFiltersVC: UIViewController, IsMediaFilterVC {
let destinationURL = URL(fileURLWithPath: NSTemporaryDirectory())
.appendingUniquePathComponent(pathExtension: YPConfig.video.fileType.fileExtension)
- _ = trimmedAsset.export(to: destinationURL) { [weak self] session in
+ _ = trimmedAsset.export(to: destinationURL, removeOldFile: true) { [weak self] session in
switch session.status {
case .completed:
DispatchQueue.main.async {
diff --git a/Source/Helpers/Permissions/YPPermissionCheckable.swift b/Source/Helpers/Permissions/YPPermissionCheckable.swift
index fb433a2c5..6f83247af 100644
--- a/Source/Helpers/Permissions/YPPermissionCheckable.swift
+++ b/Source/Helpers/Permissions/YPPermissionCheckable.swift
@@ -9,20 +9,20 @@
import UIKit
internal protocol YPPermissionCheckable {
- func doAfterLibraryPermissionCheck(block: @escaping () -> Void)
+ func doAfterLibraryPermissionCheck(block: @escaping (Bool) -> Void)
func doAfterCameraPermissionCheck(block: @escaping () -> Void)
func checkLibraryPermission()
func checkCameraPermission()
}
internal extension YPPermissionCheckable where Self: UIViewController {
- func doAfterLibraryPermissionCheck(block: @escaping () -> Void) {
+ func doAfterLibraryPermissionCheck(block: @escaping (Bool) -> Void) {
YPPermissionManager.checkLibraryPermissionAndAskIfNeeded(sourceVC: self) { hasPermission in
- if hasPermission {
- block()
- } else {
+ if !hasPermission {
ypLog("Not enough permissions.")
}
+ block(hasPermission)
+
}
}
diff --git a/Source/Pages/Gallery/YPAssetViewContainer.swift b/Source/Pages/Gallery/YPAssetViewContainer.swift
index 832d49b2f..9bdfe747e 100644
--- a/Source/Pages/Gallery/YPAssetViewContainer.swift
+++ b/Source/Pages/Gallery/YPAssetViewContainer.swift
@@ -27,7 +27,7 @@ final class YPAssetViewContainer: UIView {
public var isShown = true
public var spinnerIsShown = false
- private let spinner = UIActivityIndicatorView(style: .white)
+ public let spinner = UIActivityIndicatorView(style: .white)
private var shouldCropToSquare = YPConfig.library.isSquareByDefault
private var isMultipleSelectionEnabled = false
diff --git a/Source/Pages/Gallery/YPLibraryVC+CollectionView.swift b/Source/Pages/Gallery/YPLibraryVC+CollectionView.swift
index 89e6ac411..37e401f32 100644
--- a/Source/Pages/Gallery/YPLibraryVC+CollectionView.swift
+++ b/Source/Pages/Gallery/YPLibraryVC+CollectionView.swift
@@ -7,6 +7,7 @@
//
import UIKit
+import Photos
extension YPLibraryVC {
var isLimitExceeded: Bool { return selectedItems.count >= YPConfig.library.maxNumberOfItems }
@@ -67,8 +68,12 @@ extension YPLibraryVC {
// Replace the current selected image with the previously selected one
if let previouslySelectedIndexPath = selectedIndexPaths.last {
- v.collectionView.deselectItem(at: indexPath, animated: false)
- v.collectionView.selectItem(at: previouslySelectedIndexPath, animated: false, scrollPosition: [])
+ if(v.collectionView.indexPathsForSelectedItems?.contains(indexPath) ?? false){
+ v.collectionView.deselectItem(at: indexPath, animated: false)
+ }
+ if(v.collectionView.indexPathsForVisibleItems.contains(previouslySelectedIndexPath)){
+ v.collectionView.selectItem(at: previouslySelectedIndexPath, animated: false, scrollPosition: [])
+ }
currentlySelectedIndex = previouslySelectedIndexPath.row
changeAsset(mediaManager.getAsset(at: previouslySelectedIndexPath.row))
}
@@ -101,7 +106,19 @@ extension YPLibraryVC {
/// Checks if there can be selected more items. If no - present warning.
func checkLimit() {
- v.maxNumberWarningView.isHidden = !isLimitExceeded || isMultipleSelectionEnabled == false
+ let isHidden = !isLimitExceeded || isMultipleSelectionEnabled == false
+ v.maxNumberWarningView.isHidden = isHidden
+ self.checkSelectMoreOptions(isHidden: isHidden)
+ }
+
+ func checkSelectMoreOptions(isHidden: Bool = true) {
+ if #available(iOS 14, *) {
+ let status = PHPhotoLibrary.authorizationStatus(for: .readWrite)
+ if status == .limited {
+ v.selectMoreButton.isHidden = !isHidden
+ v.seeAllButton.isHidden = !isHidden
+ }
+ }
}
}
diff --git a/Source/Pages/Gallery/YPLibraryVC.swift b/Source/Pages/Gallery/YPLibraryVC.swift
index 53b5451f1..64ee6f41a 100644
--- a/Source/Pages/Gallery/YPLibraryVC.swift
+++ b/Source/Pages/Gallery/YPLibraryVC.swift
@@ -80,11 +80,14 @@ internal final class YPLibraryVC: UIViewController, YPPermissionCheckable {
}
guard mediaManager.hasResultItems else {
+ checkSelectMoreOptions()
return
}
if YPConfig.library.defaultMultipleSelection || selectedItems.count > 1 {
toggleMultipleSelection()
+ } else {
+ checkSelectMoreOptions()
}
}
@@ -126,6 +129,8 @@ internal final class YPLibraryVC: UIViewController, YPPermissionCheckable {
.addTarget(self,
action: #selector(multipleSelectionButtonTapped),
for: .touchUpInside)
+ v.selectMoreButton.addTarget(self,action: #selector(selectMorePhotosButtonTapped), for: .touchUpInside)
+ v.seeAllButton.addTarget(self,action: #selector(seeAllPhotosButtonTapped), for: .touchUpInside)
// Forces assetZoomableView to have a contentSize.
// otherwise 0 in first selection triggering the bug : "invalid image size 0x0"
@@ -152,11 +157,32 @@ internal final class YPLibraryVC: UIViewController, YPPermissionCheckable {
@objc
func squareCropButtonTapped() {
- doAfterLibraryPermissionCheck { [weak self] in
- self?.v.assetViewContainer.squareCropButtonTapped()
+ doAfterLibraryPermissionCheck { hasPermission in
+ if hasPermission {
+ self.v.assetViewContainer.squareCropButtonTapped()
+ }
+ }
+ }
+
+ // MARK: - Select more photos
+
+ @objc func selectMorePhotosButtonTapped() {
+ if #available(iOS 14, *) {
+ PHPhotoLibrary.shared().presentLimitedLibraryPicker(from: self)
}
}
+ // MARK: - See all photos
+
+ @objc func seeAllPhotosButtonTapped() {
+ let alertController = UIAlertController(title: "See all photos", message: "On the next screen, please click on “Photos“ and select “All Photos“", preferredStyle: .alert)
+ alertController.addAction(UIAlertAction(title: "Later", style: .default) { _ in })
+ alertController.addAction(UIAlertAction(title: "Continue", style: .default) { _ in
+ UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!, options: [:], completionHandler: nil)
+ })
+ self.present(alertController, animated: true)
+ }
+
// MARK: - Multiple Selection
@objc
@@ -170,11 +196,13 @@ internal final class YPLibraryVC: UIViewController, YPPermissionCheckable {
return
}
- doAfterLibraryPermissionCheck { [weak self] in
- if self?.isMultipleSelectionEnabled == false {
- self?.selectedItems.removeAll()
+ doAfterLibraryPermissionCheck { hasPermission in
+ if hasPermission {
+ if self.isMultipleSelectionEnabled == false {
+ self.selectedItems.removeAll()
+ }
+ self.toggleMultipleSelection()
}
- self?.toggleMultipleSelection()
}
}
@@ -261,7 +289,7 @@ internal final class YPLibraryVC: UIViewController, YPPermissionCheckable {
}
let options = PHFetchOptions()
- options.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
+ options.sortDescriptors = [NSSortDescriptor(key: YPConfig.library.sortingOption.rawValue, ascending: false)]
options.predicate = YPConfig.library.mediaType.predicate()
return options
}
@@ -409,15 +437,14 @@ internal final class YPLibraryVC: UIViewController, YPPermissionCheckable {
guard fitsVideoLengthLimits(asset: asset) else {
return
}
-
if YPConfig.video.automaticTrimToTrimmerMaxDuration {
- fetchVideoAndCropWithDuration(for: asset,
- withCropRect: resultCropRect,
- duration: YPConfig.video.trimmerMaxDuration,
- callback: callback)
+ self.fetchVideoAndCropWithDuration(for: asset,
+ withCropRect: resultCropRect,
+ duration: YPConfig.video.trimmerMaxDuration,
+ callback: callback)
} else {
- delegate?.libraryViewDidTapNext()
- mediaManager.fetchVideoUrlAndCrop(for: asset, cropRect: resultCropRect, callback: callback)
+ self.delegate?.libraryViewDidTapNext()
+ self.mediaManager.fetchVideoUrlAndCrop(for: asset, cropRect: resultCropRect, callback: callback)
}
}
@@ -447,118 +474,155 @@ internal final class YPLibraryVC: UIViewController, YPPermissionCheckable {
return (asset, $0.cropRect)
}
- // Multiple selection
- if self.isMultipleSelectionEnabled && self.selectedItems.count > 1 {
-
- // Check video length
- for asset in selectedAssets {
- if self.fitsVideoLengthLimits(asset: asset.asset) == false {
- return
- }
- }
-
- // Fill result media items array
- var resultMediaItems: [YPMediaItem] = []
- let asyncGroup = DispatchGroup()
-
- var assetDictionary: [PHAsset?: Int] = .init()
- for (index, assetPair) in selectedAssets.enumerated() {
- assetDictionary[assetPair.asset] = index
+ var isVideoSelected = false
+ let asyncCompressionGroup = DispatchGroup()
+ asyncCompressionGroup.enter()
+
+ for asset in selectedAssets {
+ if asset.asset.mediaType == .video {
+ isVideoSelected = true
+ break
}
-
- for asset in selectedAssets {
- asyncGroup.enter()
+ }
+
+ if isVideoSelected {
+ DispatchQueue.main.async {
+ let compressionOptions = YPImagePickerConfiguration.shared.video.compressionOption
+ let storyBoard = UIStoryboard(name: "YPVideoCompressionVC", bundle: Bundle(for: YPVideoCompressionVC.self))
+ let ypVideoCompressionVC = storyBoard.instantiateViewController(withIdentifier: "YPVideoCompressionVC") as! YPVideoCompressionVC
- switch asset.asset.mediaType {
- case .image:
- self.fetchImageAndCrop(for: asset.asset, withCropRect: asset.cropRect) { image, exifMeta in
- let photo = YPMediaPhoto(image: image.resizedImageIfNeeded(),
- exifMeta: exifMeta, asset: asset.asset)
- resultMediaItems.append(YPMediaItem.photo(p: photo))
- asyncGroup.leave()
- }
-
- case .video:
- self.fetchVideoAndApplySettings(for: asset.asset,
- withCropRect: asset.cropRect) { videoURL in
- if let videoURL = videoURL {
- let videoItem = YPMediaVideo(thumbnail: thumbnailFromVideoPath(videoURL),
- videoURL: videoURL, asset: asset.asset)
- resultMediaItems.append(YPMediaItem.video(v: videoItem))
- } else {
- ypLog("Problems with fetching videoURL.")
- }
- asyncGroup.leave()
- }
- default:
- break
+ var titleArray = [String]()
+ for compressionOtion in compressionOptions {
+ titleArray.append(compressionOtion.getLabel())
+ }
+ ypVideoCompressionVC.titleArray = titleArray
+ ypVideoCompressionVC.headingTitle = "Choose video quality"
+ ypVideoCompressionVC.modalPresentationStyle = .overFullScreen
+ ypVideoCompressionVC.didDismiss = {(index) in
+ YPImagePickerConfiguration.shared.video.compression = compressionOptions[index].presetID()
+ asyncCompressionGroup.leave()
}
+ self.present(ypVideoCompressionVC, animated: true, completion: nil)
}
-
- asyncGroup.notify(queue: .main) {
- // TODO: sort the array based on the initial order of the assets in selectedAssets
- resultMediaItems.sort { (first, second) -> Bool in
- var firstAsset: PHAsset?
- var secondAsset: PHAsset?
+ } else {
+ asyncCompressionGroup.leave()
+ }
+
+ asyncCompressionGroup.notify(queue: .main) {
+ DispatchQueue.global(qos: .userInitiated).async {
+ // Multiple selection
+ if self.isMultipleSelectionEnabled && self.selectedItems.count > 1 {
- switch first {
- case .photo(let photo):
- firstAsset = photo.asset
- case .video(let video):
- firstAsset = video.asset
- }
- guard let firstIndex = assetDictionary[firstAsset] else {
- return false
+ // Check video length
+ for asset in selectedAssets {
+ if self.fitsVideoLengthLimits(asset: asset.asset) == false {
+ return
+ }
}
- switch second {
- case .photo(let photo):
- secondAsset = photo.asset
- case .video(let video):
- secondAsset = video.asset
- }
+ // Fill result media items array
+ var resultMediaItems: [YPMediaItem] = []
+ let asyncGroup = DispatchGroup()
- guard let secondIndex = assetDictionary[secondAsset] else {
- return false
+ var assetDictionary: [PHAsset?: Int] = .init()
+ for (index, assetPair) in selectedAssets.enumerated() {
+ assetDictionary[assetPair.asset] = index
}
- return firstIndex < secondIndex
- }
- multipleItemsCallback(resultMediaItems)
- self.delegate?.libraryViewFinishedLoading()
- }
- } else {
- let asset = selectedAssets.first!.asset
- switch asset.mediaType {
- case .audio, .unknown:
- return
- case .video:
- self.fetchVideoAndApplySettings(for: asset, callback: { videoURL in
- DispatchQueue.main.async {
- if let videoURL = videoURL {
- self.delegate?.libraryViewFinishedLoading()
- let video = YPMediaVideo(thumbnail: thumbnailFromVideoPath(videoURL),
- videoURL: videoURL, asset: asset)
- videoCallback(video)
- } else {
- ypLog("Problems with fetching videoURL.")
+ for asset in selectedAssets {
+ asyncGroup.enter()
+
+ switch asset.asset.mediaType {
+ case .image:
+ self.fetchImageAndCrop(for: asset.asset, withCropRect: asset.cropRect) { image, exifMeta in
+ let photo = YPMediaPhoto(image: image.resizedImageIfNeeded(),
+ exifMeta: exifMeta, asset: asset.asset)
+ resultMediaItems.append(YPMediaItem.photo(p: photo))
+ asyncGroup.leave()
+ }
+
+ case .video:
+ self.fetchVideoAndApplySettings(for: asset.asset, withCropRect: asset.cropRect) { videoURL in
+ if let videoURL = videoURL {
+ let videoItem = YPMediaVideo(thumbnail: thumbnailFromVideoPath(videoURL),
+ videoURL: videoURL, asset: asset.asset)
+ resultMediaItems.append(YPMediaItem.video(v: videoItem))
+ } else {
+ ypLog("Problems with fetching videoURL.")
+ }
+ asyncGroup.leave()
+ }
+ default:
+ break
}
}
- })
- case .image:
- self.fetchImageAndCrop(for: asset) { image, exifMeta in
- DispatchQueue.main.async {
+
+ asyncGroup.notify(queue: .main) {
+ // TODO: sort the array based on the initial order of the assets in selectedAssets
+ resultMediaItems.sort { (first, second) -> Bool in
+ var firstAsset: PHAsset?
+ var secondAsset: PHAsset?
+
+ switch first {
+ case .photo(let photo):
+ firstAsset = photo.asset
+ case .video(let video):
+ firstAsset = video.asset
+ }
+ guard let firstIndex = assetDictionary[firstAsset] else {
+ return false
+ }
+
+ switch second {
+ case .photo(let photo):
+ secondAsset = photo.asset
+ case .video(let video):
+ secondAsset = video.asset
+ }
+
+ guard let secondIndex = assetDictionary[secondAsset] else {
+ return false
+ }
+
+ return firstIndex < secondIndex
+ }
+ multipleItemsCallback(resultMediaItems)
self.delegate?.libraryViewFinishedLoading()
- let photo = YPMediaPhoto(image: image.resizedImageIfNeeded(),
- exifMeta: exifMeta,
- asset: asset)
- photoCallback(photo)
}
+ } else {
+ let asset = selectedAssets.first!.asset
+ switch asset.mediaType {
+ case .audio, .unknown:
+ return
+ case .video:
+ self.fetchVideoAndApplySettings(for: asset, callback: { videoURL in
+ DispatchQueue.main.async {
+ if let videoURL = videoURL {
+ self.delegate?.libraryViewFinishedLoading()
+ let video = YPMediaVideo(thumbnail: thumbnailFromVideoPath(videoURL),
+ videoURL: videoURL, asset: asset)
+ videoCallback(video)
+ } else {
+ ypLog("Problems with fetching videoURL.")
+ }
+ }
+ })
+ case .image:
+ self.fetchImageAndCrop(for: asset) { image, exifMeta in
+ DispatchQueue.main.async {
+ self.delegate?.libraryViewFinishedLoading()
+ let photo = YPMediaPhoto(image: image.resizedImageIfNeeded(),
+ exifMeta: exifMeta,
+ asset: asset)
+ photoCallback(photo)
+ }
+ }
+ @unknown default:
+ ypLog("unknown default reached. Check code.")
+ }
+ return
}
- @unknown default:
- ypLog("unknown default reached. Check code.")
}
- return
}
}
}
diff --git a/Source/Pages/Gallery/YPLibraryView.swift b/Source/Pages/Gallery/YPLibraryView.swift
index d42db8866..32503c92c 100644
--- a/Source/Pages/Gallery/YPLibraryView.swift
+++ b/Source/Pages/Gallery/YPLibraryView.swift
@@ -48,6 +48,32 @@ internal final class YPLibraryView: UIView {
v.font = YPConfig.fonts.libaryWarningFont
return v
}()
+ internal let selectMoreButton: UIButton = {
+ let v = UIButton()
+ var status: PHAuthorizationStatus
+ v.setTitle(" Select more ", for: .normal)
+ v.backgroundColor = YPConfig.selectMoreButtonBackgroundColour.withAlphaComponent(0.8)
+ v.layer.cornerRadius = 4
+ v.layer.masksToBounds = true
+ v.tintColor = UIColor.ypLabel
+ v.isHidden = true
+ return v
+ }()
+ internal let seeAllButton: UIButton = {
+ let v = UIButton()
+ var status: PHAuthorizationStatus
+ if YPConfig.library.mediaType == .video {
+ v.setTitle(" See all videos ", for: .normal)
+ } else {
+ v.setTitle(" See all photos ", for: .normal)
+ }
+ v.backgroundColor = YPConfig.seeAllPhotosButtonBackgroundColour.withAlphaComponent(0.8)
+ v.layer.cornerRadius = 4
+ v.layer.masksToBounds = true
+ v.tintColor = UIColor.ypLabel
+ v.isHidden = true
+ return v
+ }()
// MARK: - Private vars
@@ -129,6 +155,10 @@ internal final class YPLibraryView: UIView {
shouldShowLoader = false
assetViewContainer.spinnerView.alpha = 0
}
+
+ func stopSpinner() {
+ assetViewContainer.spinner.stopAnimating()
+ }
func updateProgress(_ progress: Float) {
progressView.isHidden = progress > 0.99 || progress == 0
@@ -178,7 +208,9 @@ internal final class YPLibraryView: UIView {
progressView,
maxNumberWarningView.subviews(
maxNumberWarningLabel
- )
+ ),
+ selectMoreButton,
+ seeAllButton
)
collectionContainerView.fillContainer()
@@ -200,5 +232,15 @@ internal final class YPLibraryView: UIView {
|maxNumberWarningView|.bottom(0)
maxNumberWarningView.Top == safeAreaLayoutGuide.Bottom - 40
maxNumberWarningLabel.centerHorizontally().top(11)
+
+ seeAllButton.Bottom == safeAreaLayoutGuide.Bottom - 8
+ seeAllButton.Top == safeAreaLayoutGuide.Bottom - 48
+ seeAllButton.widthAnchor.constraint(equalTo: self.widthAnchor, multiplier: 0.50).isActive = true
+ seeAllButton.Left == UIScreen.main.bounds.width * 0.05
+
+ selectMoreButton.Bottom == safeAreaLayoutGuide.Bottom - 8
+ selectMoreButton.Top == safeAreaLayoutGuide.Bottom - 48
+ selectMoreButton.widthAnchor.constraint(equalTo: self.widthAnchor, multiplier: 0.35).isActive = true
+ selectMoreButton.Right == UIScreen.main.bounds.width * 0.05
}
}
diff --git a/Source/Resources/Assets.xcassets/Contents.json b/Source/Resources/Assets.xcassets/Contents.json
index da4a164c9..73c00596a 100644
--- a/Source/Resources/Assets.xcassets/Contents.json
+++ b/Source/Resources/Assets.xcassets/Contents.json
@@ -1,6 +1,6 @@
{
"info" : {
- "version" : 1,
- "author" : "xcode"
+ "author" : "xcode",
+ "version" : 1
}
-}
\ No newline at end of file
+}
diff --git a/Source/Resources/Assets.xcassets/SuccessTickSmallRed.imageset/Contents.json b/Source/Resources/Assets.xcassets/SuccessTickSmallRed.imageset/Contents.json
new file mode 100644
index 000000000..a9071d9e9
--- /dev/null
+++ b/Source/Resources/Assets.xcassets/SuccessTickSmallRed.imageset/Contents.json
@@ -0,0 +1,22 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "Success Tick@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "Success Tick@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Source/Resources/Assets.xcassets/SuccessTickSmallRed.imageset/Success Tick@2x.png b/Source/Resources/Assets.xcassets/SuccessTickSmallRed.imageset/Success Tick@2x.png
new file mode 100644
index 000000000..f05a6c231
Binary files /dev/null and b/Source/Resources/Assets.xcassets/SuccessTickSmallRed.imageset/Success Tick@2x.png differ
diff --git a/Source/Resources/Assets.xcassets/SuccessTickSmallRed.imageset/Success Tick@3x.png b/Source/Resources/Assets.xcassets/SuccessTickSmallRed.imageset/Success Tick@3x.png
new file mode 100644
index 000000000..ff53dc0e9
Binary files /dev/null and b/Source/Resources/Assets.xcassets/SuccessTickSmallRed.imageset/Success Tick@3x.png differ
diff --git a/Source/YPImagePicker.swift b/Source/YPImagePicker.swift
index 37dc79758..9d5358f86 100644
--- a/Source/YPImagePicker.swift
+++ b/Source/YPImagePicker.swift
@@ -99,58 +99,59 @@ open class YPImagePicker: UINavigationController {
}
// One item flow
- let item = items.first!
- switch item {
- case .photo(let photo):
- let completion = { (photo: YPMediaPhoto) in
- let mediaItem = YPMediaItem.photo(p: photo)
- // Save new image or existing but modified, to the photo album.
- if YPConfig.shouldSaveNewPicturesToAlbum {
- let isModified = photo.modifiedImage != nil
- if photo.fromCamera || (!photo.fromCamera && isModified) {
- YPPhotoSaver.trySaveImage(photo.image, inAlbumNamed: YPConfig.albumName)
+ if let item = items.first {
+ switch item {
+ case .photo(let photo):
+ let completion = { (photo: YPMediaPhoto) in
+ let mediaItem = YPMediaItem.photo(p: photo)
+ // Save new image or existing but modified, to the photo album.
+ if YPConfig.shouldSaveNewPicturesToAlbum {
+ let isModified = photo.modifiedImage != nil
+ if photo.fromCamera || (!photo.fromCamera && isModified) {
+ YPPhotoSaver.trySaveImage(photo.image, inAlbumNamed: YPConfig.albumName)
+ }
+ }
+ self?.didSelect(items: [mediaItem])
}
- }
- self?.didSelect(items: [mediaItem])
- }
-
- func showCropVC(photo: YPMediaPhoto, completion: @escaping (_ aphoto: YPMediaPhoto) -> Void) {
- switch YPConfig.showsCrop {
- case .rectangle, .circle:
- let cropVC = YPCropVC(image: photo.image)
- cropVC.didFinishCropping = { croppedImage in
- photo.modifiedImage = croppedImage
- completion(photo)
+
+ func showCropVC(photo: YPMediaPhoto, completion: @escaping (_ aphoto: YPMediaPhoto) -> Void) {
+ switch YPConfig.showsCrop {
+ case .rectangle, .circle:
+ let cropVC = YPCropVC(image: photo.image)
+ cropVC.didFinishCropping = { croppedImage in
+ photo.modifiedImage = croppedImage
+ completion(photo)
+ }
+ self?.pushViewController(cropVC, animated: true)
+ default:
+ completion(photo)
+ }
}
- self?.pushViewController(cropVC, animated: true)
- default:
- completion(photo)
- }
- }
-
- if YPConfig.showsPhotoFilters {
- let filterVC = YPPhotoFiltersVC(inputPhoto: photo,
- isFromSelectionVC: false)
- // Show filters and then crop
- filterVC.didSave = { outputMedia in
- if case let YPMediaItem.photo(outputPhoto) = outputMedia {
- showCropVC(photo: outputPhoto, completion: completion)
+
+ if YPConfig.showsPhotoFilters {
+ let filterVC = YPPhotoFiltersVC(inputPhoto: photo,
+ isFromSelectionVC: false)
+ // Show filters and then crop
+ filterVC.didSave = { outputMedia in
+ if case let YPMediaItem.photo(outputPhoto) = outputMedia {
+ showCropVC(photo: outputPhoto, completion: completion)
+ }
+ }
+ self?.pushViewController(filterVC, animated: false)
+ } else {
+ showCropVC(photo: photo, completion: completion)
+ }
+ case .video(let video):
+ if YPConfig.showsVideoTrimmer {
+ let videoFiltersVC = YPVideoFiltersVC.initWith(video: video,
+ isFromSelectionVC: false)
+ videoFiltersVC.didSave = { [weak self] outputMedia in
+ self?.didSelect(items: [outputMedia])
+ }
+ self?.pushViewController(videoFiltersVC, animated: true)
+ } else {
+ self?.didSelect(items: [YPMediaItem.video(v: video)])
}
- }
- self?.pushViewController(filterVC, animated: false)
- } else {
- showCropVC(photo: photo, completion: completion)
- }
- case .video(let video):
- if YPConfig.showsVideoTrimmer {
- let videoFiltersVC = YPVideoFiltersVC.initWith(video: video,
- isFromSelectionVC: false)
- videoFiltersVC.didSave = { [weak self] outputMedia in
- self?.didSelect(items: [outputMedia])
- }
- self?.pushViewController(videoFiltersVC, animated: true)
- } else {
- self?.didSelect(items: [YPMediaItem.video(v: video)])
}
}
}
diff --git a/Source/YPPickerVC.swift b/Source/YPPickerVC.swift
index 64f361ff9..b67e70c8e 100644
--- a/Source/YPPickerVC.swift
+++ b/Source/YPPickerVC.swift
@@ -166,8 +166,12 @@ open class YPPickerVC: YPBottomPager, YPBottomPagerDelegate {
// Re-trigger permission check
if let vc = vc as? YPLibraryVC {
- vc.doAfterLibraryPermissionCheck { [weak vc] in
- vc?.initialize()
+ vc.doAfterLibraryPermissionCheck { hasPermission in
+ if hasPermission {
+ vc.initialize()
+ } else {
+ vc.v.stopSpinner()
+ }
}
} else if let cameraVC = vc as? YPCameraVC {
cameraVC.start()
@@ -379,6 +383,7 @@ extension YPPickerVC: YPLibraryViewDelegate {
public func libraryViewHaveNoItems() {
pickerVCDelegate?.libraryHasNoItems()
+ self.libraryVC?.v.stopSpinner()
}
public func libraryViewShouldAddToSelection(indexPath: IndexPath, numSelections: Int) -> Bool {
diff --git a/YPImagePicker.podspec b/YPImagePicker.podspec
index df06a95b3..f29f89732 100644
--- a/YPImagePicker.podspec
+++ b/YPImagePicker.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'YPImagePicker'
- s.version = "5.2.1"
+ s.version = "5.3.0"
s.summary = "Instagram-like image picker & filters for iOS"
s.homepage = "https://github.com/Yummypets/YPImagePicker"
s.license = { :type => "MIT", :file => "LICENSE" }
@@ -13,7 +13,7 @@ Pod::Spec.new do |s|
s.source_files = 'Source/**/*.swift'
s.dependency 'SteviaLayout', '= 5.1.2'
s.dependency 'PryntTrimmerView', '= 4.0.2'
- s.resources = ['Source/Resources/*', 'Source/**/*.xib']
+ s.resources = ['Source/Resources/*', 'Source/**/*.xib', 'Source/**/*.storyboard']
s.description = "Instagram-like image picker & filters for iOS supporting videos and albums"
s.swift_versions = ['5.0', '5.1', '5.2', '5.3']
end
diff --git a/YPImagePicker.xcodeproj/project.pbxproj b/YPImagePicker.xcodeproj/project.pbxproj
index 88b6475ec..1f60500e0 100644
--- a/YPImagePicker.xcodeproj/project.pbxproj
+++ b/YPImagePicker.xcodeproj/project.pbxproj
@@ -56,6 +56,10 @@
99CF6D2B201CB96700487F77 /* YPVideoCaptureHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 99CF6D2A201CB96700487F77 /* YPVideoCaptureHelper.swift */; };
99D1DC2B1F9788930047F0E0 /* YPImagePickerConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 99D1DC2A1F9788930047F0E0 /* YPImagePickerConfiguration.swift */; };
AA69BCF222E601D100FBB925 /* YPDeviceOrientationHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA69BCF122E601D100FBB925 /* YPDeviceOrientationHelper.swift */; };
+ C86AD84028F3D2E500E2EB89 /* YPVideoCompressionVC.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C86AD83F28F3D2E500E2EB89 /* YPVideoCompressionVC.storyboard */; };
+ C86AD84128F3D2E500E2EB89 /* YPVideoCompressionVC.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C86AD83F28F3D2E500E2EB89 /* YPVideoCompressionVC.storyboard */; };
+ C8F28E7228F34E5800E9290E /* YPVideoCompressionVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8F28E7128F34E5800E9290E /* YPVideoCompressionVC.swift */; };
+ C8F28E7328F34E5800E9290E /* YPVideoCompressionVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8F28E7128F34E5800E9290E /* YPVideoCompressionVC.swift */; };
EB05F6E7214A7191002040AA /* YPVideoProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB05F6E6214A7191002040AA /* YPVideoProcessor.swift */; };
EB1AB2EA20AC1DED00BFA79F /* CGFloat+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB1AB2E920AC1DED00BFA79F /* CGFloat+Extensions.swift */; };
EB473E17208E192800D16105 /* URL+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB473E16208E192800D16105 /* URL+Extensions.swift */; };
@@ -282,6 +286,8 @@
A7FD716620755C2D0044A8E8 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/YPImagePickerLocalizable.strings; sourceTree = ""; };
AA69BCF122E601D100FBB925 /* YPDeviceOrientationHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YPDeviceOrientationHelper.swift; sourceTree = ""; };
BEED427CB4F6E5B8C20B6F13 /* Pods-Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example.release.xcconfig"; path = "Target Support Files/Pods-Example/Pods-Example.release.xcconfig"; sourceTree = ""; };
+ C86AD83F28F3D2E500E2EB89 /* YPVideoCompressionVC.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = YPVideoCompressionVC.storyboard; sourceTree = ""; };
+ C8F28E7128F34E5800E9290E /* YPVideoCompressionVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YPVideoCompressionVC.swift; sourceTree = ""; };
DC3DAC4526C6FCAA007FD95A /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cs; path = cs.lproj/YPImagePickerLocalizable.strings; sourceTree = ""; };
E3E492BB2169012B002BA807 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = ko.lproj/YPImagePickerLocalizable.strings; sourceTree = ""; };
E5287F5820B908720052153D /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/YPImagePickerLocalizable.strings; sourceTree = ""; };
@@ -565,7 +571,9 @@
isa = PBXGroup;
children = (
EB59F450208766B800811B7B /* YPVideoFiltersVC.swift */,
+ C8F28E7128F34E5800E9290E /* YPVideoCompressionVC.swift */,
EBB0FF7920877A7500C84E25 /* YPVideoView.swift */,
+ C86AD83F28F3D2E500E2EB89 /* YPVideoCompressionVC.storyboard */,
);
path = Video;
sourceTree = "";
@@ -723,7 +731,6 @@
};
EBA37B4E26F749C6005DAAD4 = {
CreatedOnToolsVersion = 12.5.1;
- DevelopmentTeam = B3U3XRF8D7;
ProvisioningStyle = Automatic;
};
};
@@ -783,6 +790,7 @@
files = (
8458057421819B95004F241C /* YPImagePickerLocalizable.strings in Resources */,
99C6D6B91F1FB5C100711DB2 /* Assets.xcassets in Resources */,
+ C86AD84128F3D2E500E2EB89 /* YPVideoCompressionVC.storyboard in Resources */,
99C6D6BD1F1FB5C100711DB2 /* YPLibraryView.xib in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -795,6 +803,7 @@
EBA37BC426F750DE005DAAD4 /* YPLibraryView.xib in Resources */,
EBA37B5B26F749C7005DAAD4 /* Assets.xcassets in Resources */,
EBA37BC726F75151005DAAD4 /* YPImagePickerLocalizable.strings in Resources */,
+ C86AD84028F3D2E500E2EB89 /* YPVideoCompressionVC.storyboard in Resources */,
EBA37BC626F75144005DAAD4 /* Assets.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -879,6 +888,7 @@
EBA37BC026F74CE0005DAAD4 /* YPFiltersView.swift in Sources */,
99CF6D1B201B6A5C00487F77 /* UICollectionView+Extensions.swift in Sources */,
EBA37B0A26F73080005DAAD4 /* YPAlbumVC.swift in Sources */,
+ C8F28E7328F34E5800E9290E /* YPVideoCompressionVC.swift in Sources */,
99C6D6C11F1FB5C100711DB2 /* YPAssetViewContainer.swift in Sources */,
EB473E17208E192800D16105 /* URL+Extensions.swift in Sources */,
EB473E2B208E1ECB00D16105 /* AVCaptureDevice+Extensions.swift in Sources */,
@@ -957,6 +967,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ C8F28E7228F34E5800E9290E /* YPVideoCompressionVC.swift in Sources */,
EBA37BBB26F74CE0005DAAD4 /* YPPhotoFiltersVC.swift in Sources */,
EBA37B8F26F74CBA005DAAD4 /* AVFileType+Extensions.swift in Sources */,
EBA37B7026F74CBA005DAAD4 /* YPError.swift in Sources */,
@@ -1241,7 +1252,7 @@
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
- MARKETING_VERSION = 5.2.1;
+ MARKETING_VERSION = 5.3.0;
ONLY_ACTIVE_ARCH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.yummypets.YPImagePicker;
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -1278,7 +1289,7 @@
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
- MARKETING_VERSION = 5.2.1;
+ MARKETING_VERSION = 5.3.0;
ONLY_ACTIVE_ARCH = NO;
PRODUCT_BUNDLE_IDENTIFIER = com.yummypets.YPImagePicker;
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -1301,7 +1312,7 @@
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic;
- DEVELOPMENT_TEAM = B3U3XRF8D7;
+ DEVELOPMENT_TEAM = WQTCKL2Y64;
GCC_C_LANGUAGE_STANDARD = gnu11;
INFOPLIST_FILE = Example/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
@@ -1332,7 +1343,7 @@
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic;
- DEVELOPMENT_TEAM = B3U3XRF8D7;
+ DEVELOPMENT_TEAM = WQTCKL2Y64;
GCC_C_LANGUAGE_STANDARD = gnu11;
INFOPLIST_FILE = Example/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
diff --git a/YPImagePicker.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/YPImagePicker.xcodeproj/project.xcworkspace/contents.xcworkspacedata
index c50e3a4d5..919434a62 100644
--- a/YPImagePicker.xcodeproj/project.xcworkspace/contents.xcworkspacedata
+++ b/YPImagePicker.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -2,6 +2,6 @@
+ location = "self:">
diff --git a/YPImagePicker.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/YPImagePicker.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
new file mode 100644
index 000000000..278c37f40
--- /dev/null
+++ b/YPImagePicker.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
@@ -0,0 +1,23 @@
+{
+ "pins" : [
+ {
+ "identity" : "prynttrimmerview",
+ "kind" : "remoteSourceControl",
+ "location" : "https://github.com/HHK1/PryntTrimmerView",
+ "state" : {
+ "revision" : "ac1b60a22c7e6a6514de7a66d2f3d5b537c956d5",
+ "version" : "4.0.2"
+ }
+ },
+ {
+ "identity" : "stevia",
+ "kind" : "remoteSourceControl",
+ "location" : "https://github.com/freshOS/Stevia",
+ "state" : {
+ "revision" : "cfb1a1d2159277bb553c3dc46f3f742c0275566d",
+ "version" : "5.1.2"
+ }
+ }
+ ],
+ "version" : 2
+}
diff --git a/YPImagePicker.xcodeproj/xcshareddata/xcschemes/Example.xcscheme b/YPImagePicker.xcodeproj/xcshareddata/xcschemes/Example.xcscheme
index 2467dde78..d7a616739 100644
--- a/YPImagePicker.xcodeproj/xcshareddata/xcschemes/Example.xcscheme
+++ b/YPImagePicker.xcodeproj/xcshareddata/xcschemes/Example.xcscheme
@@ -1,6 +1,6 @@
+
+
+
+ PreviewsEnabled
+
+
+