From c4da74e10982ec35d426a32692ab1593578119fa Mon Sep 17 00:00:00 2001 From: Andrey Sak Date: Fri, 2 Aug 2024 11:53:59 +0300 Subject: [PATCH 1/2] Summary screen example --- Example/Example.xcodeproj/project.pbxproj | 4 ++ Example/Example/SummaryViewController.swift | 61 +++++++++++++++++++++ Example/Example/VideoEditorModule.swift | 4 ++ Example/Example/ViewController.swift | 53 +++++++++++++++++- 4 files changed, 120 insertions(+), 2 deletions(-) create mode 100644 Example/Example/SummaryViewController.swift diff --git a/Example/Example.xcodeproj/project.pbxproj b/Example/Example.xcodeproj/project.pbxproj index f65a48dd..57fbf9d6 100644 --- a/Example/Example.xcodeproj/project.pbxproj +++ b/Example/Example.xcodeproj/project.pbxproj @@ -19,6 +19,7 @@ 70113E7129C1D01800CBA08B /* VideoEditorModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70113E7029C1D01800CBA08B /* VideoEditorModule.swift */; }; 8A32EED0258CB5430098F852 /* bundleEffects in Resources */ = {isa = PBXBuildFile; fileRef = 8A32EECF258CB5430098F852 /* bundleEffects */; }; 8A32EEDF258CB70C0098F852 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8A32EEDE258CB70C0098F852 /* Assets.xcassets */; }; + DBD546942C5CC7D7003157BA /* SummaryViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBD546932C5CC7D7003157BA /* SummaryViewController.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -41,6 +42,7 @@ 8AFC95CF269DC12D00B4114B /* BNBLicenseUtils.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = BNBLicenseUtils.xcframework; sourceTree = ""; }; 8D879ADE024EEEC9574AAB2D /* 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 = ""; }; A24378930003F0F910117502 /* Pods_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + DBD546932C5CC7D7003157BA /* SummaryViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SummaryViewController.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -102,6 +104,7 @@ 70113E7029C1D01800CBA08B /* VideoEditorModule.swift */, 636C55232B0DF24100678849 /* PhotoEditorModule.swift */, 639DA00F254700290011C153 /* ViewController.swift */, + DBD546932C5CC7D7003157BA /* SummaryViewController.swift */, 63F7115F29D1F21A00045A06 /* short_music_20.wav */, 634FAC06255C351900FB0DBC /* Localizable.strings */, 639DA011254700290011C153 /* Main.storyboard */, @@ -252,6 +255,7 @@ 636C55242B0DF24100678849 /* PhotoEditorModule.swift in Sources */, 70113E7129C1D01800CBA08B /* VideoEditorModule.swift in Sources */, 639DA00C254700290011C153 /* AppDelegate.swift in Sources */, + DBD546942C5CC7D7003157BA /* SummaryViewController.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Example/Example/SummaryViewController.swift b/Example/Example/SummaryViewController.swift new file mode 100644 index 00000000..5bc04022 --- /dev/null +++ b/Example/Example/SummaryViewController.swift @@ -0,0 +1,61 @@ +// +// SummaryViewController.swift +// Example +// +// Created by Andrey Sak on 2.08.24. +// + +import UIKit + +class SummaryViewController: UIViewController { + + var editCoverHandler: (() -> Void)? + + var coverImage: UIImage? + + private let coverImageView: UIImageView = { + let imageView = UIImageView() + imageView.clipsToBounds = true + imageView.contentMode = .scaleAspectFill + return imageView + }() + + private let editCoverButton: UIButton = { + let button = UIButton() + button.layer.borderColor = UIColor.white.cgColor + button.layer.borderWidth = 2.0 + button.setTitle("Edit cover", for: .normal) + return button + }() + + override func viewDidLoad() { + super.viewDidLoad() + + view.backgroundColor = UIColor.gray + + view.addSubview(coverImageView) + coverImageView.image = coverImage + coverImageView.translatesAutoresizingMaskIntoConstraints = false + NSLayoutConstraint.activate([ + coverImageView.widthAnchor.constraint(equalToConstant: 180), + coverImageView.heightAnchor.constraint(equalToConstant: 320), + coverImageView.centerXAnchor.constraint(equalTo: view.centerXAnchor), + coverImageView.centerYAnchor.constraint(equalTo: view.centerYAnchor) + ]) + + view.addSubview(editCoverButton) + editCoverButton.addTarget(self, action: #selector(editCoverAction), for: .touchUpInside) + editCoverButton.translatesAutoresizingMaskIntoConstraints = false + NSLayoutConstraint.activate([ + editCoverButton.widthAnchor.constraint(equalToConstant: 140), + editCoverButton.heightAnchor.constraint(equalToConstant: 45), + editCoverButton.centerXAnchor.constraint(equalTo: coverImageView.centerXAnchor), + editCoverButton.topAnchor.constraint(equalTo: coverImageView.bottomAnchor, constant: 10.0) + ]) + } + + @IBAction func editCoverAction(_ sender: Any) { + // 6. Back to editing cover + editCoverHandler?() + } +} diff --git a/Example/Example/VideoEditorModule.swift b/Example/Example/VideoEditorModule.swift index c9ce2a1c..c7325d21 100644 --- a/Example/Example/VideoEditorModule.swift +++ b/Example/Example/VideoEditorModule.swift @@ -27,6 +27,10 @@ class VideoEditorModule { configuration: config ) + var videoEditorArguments: [String: Any] = [:] + videoEditorArguments["ENABLE_NEW_UI"] = true + videoEditorSDK?.updateVideoEditorArgs(videoEditorArguments) + self.videoEditorSDK = videoEditorSDK } diff --git a/Example/Example/ViewController.swift b/Example/Example/ViewController.swift index aaa0d67b..3793822e 100644 --- a/Example/Example/ViewController.swift +++ b/Example/Example/ViewController.swift @@ -34,9 +34,58 @@ class ViewController: UIViewController, BanubaVideoEditorDelegate, BanubaPhotoEd } func videoEditorDone(_ videoEditor: BanubaVideoEditor) { - videoEditor.dismissVideoEditor(animated: true) { [weak self] in - self?.exportVideo(videoEditor: videoEditor) + // 1. Export video + + guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene, + let window = windowScene.windows.first, + let presentedViewController = window.rootViewController?.presentedViewController else { + return + } + + let progressViewController = videoEditorModule!.createProgressViewController() + progressViewController.cancelHandler = { videoEditor.stopExport() } + + presentedViewController.present(progressViewController, animated: true) + + let manager = FileManager.default + let exportedVideoFileName = "tmp.mov" + let videoURL = manager.temporaryDirectory.appendingPathComponent(exportedVideoFileName) + if manager.fileExists(atPath: videoURL.path) { + try? manager.removeItem(at: videoURL) } + + let exportConfiguration = videoEditorModule!.createExportConfiguration(destFile: videoURL) + + videoEditor.export( + using: exportConfiguration, + exportProgress: { [weak progressViewController] progress in + DispatchQueue.main.async { + progressViewController?.updateProgressView(with: Float(progress)) + } + }, + completion: { [weak presentedViewController, weak progressViewController] error, exportCoverImages in + DispatchQueue.main.async { + progressViewController?.dismiss(animated: true) { + guard error == nil else { + Logger.logError("error with exporting video \(error!)") + return + } + // 2. Open summary view controller + let summaryViewController = SummaryViewController() + // 3. Prepopulate summaryVC with cover image + summaryViewController.coverImage = exportCoverImages?.coverImage + + let navigationController = presentedViewController as? UINavigationController + summaryViewController.editCoverHandler = { [weak navigationController] in + // 5. Return to cover screen if needed + navigationController?.popViewController(animated: true) + } + + // 4. Show summary screen + navigationController?.pushViewController(summaryViewController, animated: true) + } + } + }) } // MARK: - Actions From 2a676a2215186dda54661890d5ca683f06c9da26 Mon Sep 17 00:00:00 2001 From: Andrey Sak Date: Mon, 5 Aug 2024 14:14:57 +0300 Subject: [PATCH 2/2] add back button on summary screen --- .../nav_back_arrow.imageset/Contents.json | 21 ++++++++++++++++++ .../icon-chevron-left-l.pdf | Bin 0 -> 5563 bytes Example/Example/SummaryViewController.swift | 16 +++++++++++++ 3 files changed, 37 insertions(+) create mode 100644 Example/Example/Assets.xcassets/nav_back_arrow.imageset/Contents.json create mode 100644 Example/Example/Assets.xcassets/nav_back_arrow.imageset/icon-chevron-left-l.pdf diff --git a/Example/Example/Assets.xcassets/nav_back_arrow.imageset/Contents.json b/Example/Example/Assets.xcassets/nav_back_arrow.imageset/Contents.json new file mode 100644 index 00000000..6543f7ca --- /dev/null +++ b/Example/Example/Assets.xcassets/nav_back_arrow.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "icon-chevron-left-l.pdf", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/Example/Assets.xcassets/nav_back_arrow.imageset/icon-chevron-left-l.pdf b/Example/Example/Assets.xcassets/nav_back_arrow.imageset/icon-chevron-left-l.pdf new file mode 100644 index 0000000000000000000000000000000000000000..11ee31e530e1e2aa986db97ecaea36b14d2c06b9 GIT binary patch literal 5563 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 IQDn$}0F3`OvH$=8 literal 0 HcmV?d00001 diff --git a/Example/Example/SummaryViewController.swift b/Example/Example/SummaryViewController.swift index 5bc04022..e6f2b9de 100644 --- a/Example/Example/SummaryViewController.swift +++ b/Example/Example/SummaryViewController.swift @@ -20,6 +20,12 @@ class SummaryViewController: UIViewController { return imageView }() + private let backButton: UIButton = { + let button = UIButton() + button.setImage(UIImage(resource: .navBackArrow), for: .normal) + return button + }() + private let editCoverButton: UIButton = { let button = UIButton() button.layer.borderColor = UIColor.white.cgColor @@ -43,6 +49,16 @@ class SummaryViewController: UIViewController { coverImageView.centerYAnchor.constraint(equalTo: view.centerYAnchor) ]) + view.addSubview(backButton) + backButton.addTarget(self, action: #selector(editCoverAction), for: .touchUpInside) + backButton.translatesAutoresizingMaskIntoConstraints = false + NSLayoutConstraint.activate([ + backButton.widthAnchor.constraint(equalToConstant: 45), + backButton.heightAnchor.constraint(equalToConstant: 45), + backButton.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 10.0), + backButton.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 60.0) + ]) + view.addSubview(editCoverButton) editCoverButton.addTarget(self, action: #selector(editCoverAction), for: .touchUpInside) editCoverButton.translatesAutoresizingMaskIntoConstraints = false