From d18fb794cbc0cbfb08c470039db8ab6b106f3a28 Mon Sep 17 00:00:00 2001 From: Mustafa Merza <mustafa.merza95@gmail.com> Date: Tue, 13 Aug 2024 12:28:31 +0300 Subject: [PATCH] - Added scan session preview screen to display scan sessions in a zoomable images pager. --- MiniScanner.xcodeproj/project.pbxproj | 20 ++ .../DocumentPreviewViewController.swift | 5 +- .../ScanSessionPreviewViewController.swift | 171 ++++++++++++++++++ .../ScanSessionPreviewViewController.xib | 121 +++++++++++++ .../ScannedItemPreviewPagerViewCell.swift | 69 +++++++ .../EditViewController.swift | 15 +- 6 files changed, 393 insertions(+), 8 deletions(-) create mode 100644 MiniScanner/Modules/DocumentPreview/ScanSessionPreview/ScanSessionPreviewViewController.swift create mode 100644 MiniScanner/Modules/DocumentPreview/ScanSessionPreview/ScanSessionPreviewViewController.xib create mode 100644 MiniScanner/Modules/DocumentPreview/ScanSessionPreview/ScannedItemPreviewPagerViewCell.swift diff --git a/MiniScanner.xcodeproj/project.pbxproj b/MiniScanner.xcodeproj/project.pbxproj index 544f23a..52fb0a0 100644 --- a/MiniScanner.xcodeproj/project.pbxproj +++ b/MiniScanner.xcodeproj/project.pbxproj @@ -247,6 +247,9 @@ 67A20DE12C57BC56009D2F25 /* DocumentsCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67A20DDF2C57BC56009D2F25 /* DocumentsCollectionViewCell.swift */; }; 67A20DE22C57BC56009D2F25 /* DocumentsCollectionViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 67A20DE02C57BC56009D2F25 /* DocumentsCollectionViewCell.xib */; }; 67A20DE42C57BC89009D2F25 /* DocumentsCellDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67A20DE32C57BC89009D2F25 /* DocumentsCellDelegate.swift */; }; + 67A2AF6E2C6B46D100039F30 /* ScanSessionPreviewViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67A2AF6C2C6B46D100039F30 /* ScanSessionPreviewViewController.swift */; }; + 67A2AF6F2C6B46D100039F30 /* ScanSessionPreviewViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 67A2AF6D2C6B46D100039F30 /* ScanSessionPreviewViewController.xib */; }; + 67A2AF712C6B4A5400039F30 /* ScannedItemPreviewPagerViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67A2AF702C6B4A5400039F30 /* ScannedItemPreviewPagerViewCell.swift */; }; 67D714B52C5161A30065E6F4 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 67D714B42C5161A30065E6F4 /* Images.xcassets */; }; 67E6A1962C64DEB400A77F29 /* ScannedItemType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67E6A1952C64DEB400A77F29 /* ScannedItemType.swift */; }; 67E6A1982C65151F00A77F29 /* ImageCompressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67E6A1972C65151F00A77F29 /* ImageCompressView.swift */; }; @@ -542,6 +545,9 @@ 67A20DDF2C57BC56009D2F25 /* DocumentsCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DocumentsCollectionViewCell.swift; sourceTree = "<group>"; }; 67A20DE02C57BC56009D2F25 /* DocumentsCollectionViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = DocumentsCollectionViewCell.xib; sourceTree = "<group>"; }; 67A20DE32C57BC89009D2F25 /* DocumentsCellDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DocumentsCellDelegate.swift; sourceTree = "<group>"; }; + 67A2AF6C2C6B46D100039F30 /* ScanSessionPreviewViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScanSessionPreviewViewController.swift; sourceTree = "<group>"; }; + 67A2AF6D2C6B46D100039F30 /* ScanSessionPreviewViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ScanSessionPreviewViewController.xib; sourceTree = "<group>"; }; + 67A2AF702C6B4A5400039F30 /* ScannedItemPreviewPagerViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScannedItemPreviewPagerViewCell.swift; sourceTree = "<group>"; }; 67D714B42C5161A30065E6F4 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; }; 67E6A1952C64DEB400A77F29 /* ScannedItemType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScannedItemType.swift; sourceTree = "<group>"; }; 67E6A1972C65151F00A77F29 /* ImageCompressView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageCompressView.swift; sourceTree = "<group>"; }; @@ -1423,6 +1429,16 @@ path = DocumentsCollectionViewCell; sourceTree = "<group>"; }; + 67A2AF672C6B466300039F30 /* ScanSessionPreview */ = { + isa = PBXGroup; + children = ( + 67A2AF6D2C6B46D100039F30 /* ScanSessionPreviewViewController.xib */, + 67A2AF6C2C6B46D100039F30 /* ScanSessionPreviewViewController.swift */, + 67A2AF702C6B4A5400039F30 /* ScannedItemPreviewPagerViewCell.swift */, + ); + path = ScanSessionPreview; + sourceTree = "<group>"; + }; 98E49D3F46C8E62718825860 /* Pods */ = { isa = PBXGroup; children = ( @@ -1562,6 +1578,7 @@ EC8A9B2C254DE94900F9AF99 /* DocumentPreview */ = { isa = PBXGroup; children = ( + 67A2AF672C6B466300039F30 /* ScanSessionPreview */, 6794328A2C689E78002E5F8D /* Compress */, ECA1FAA0254DEA6A0081F00B /* DocumentPreview.storyboard */, EC8A9B26254DE91B00F9AF99 /* DocumentPreviewViewController.swift */, @@ -1690,6 +1707,7 @@ 53BEB1432C2967E0005A3567 /* FoldersViewController.xib in Resources */, 53014FAC2C11A8E80071CE39 /* rotate@3x.png in Resources */, 535984112C145083003EB6ED /* Poppins-Regular.ttf in Resources */, + 67A2AF6F2C6B46D100039F30 /* ScanSessionPreviewViewController.xib in Resources */, 53CD5F532C15022E0010424B /* KNAlertViewController.xib in Resources */, EC0CF20A254D8BC000888722 /* LaunchScreen.storyboard in Resources */, 53014FAB2C11A8E80071CE39 /* flash.png in Resources */, @@ -1812,6 +1830,7 @@ 535983EF2C142C9F003EB6ED /* Localization.swift in Sources */, 539996892C27130000671340 /* ConstraintDSL.swift in Sources */, 539996952C27130000671340 /* ConstraintConstantTarget.swift in Sources */, + 67A2AF712C6B4A5400039F30 /* ScannedItemPreviewPagerViewCell.swift in Sources */, 672C46622C47C74300497EF0 /* DependencyInjector.swift in Sources */, 677E65F02C5A6F0E0039E2C5 /* MoveScanSessionUseCase.swift in Sources */, 539996902C27130000671340 /* UILayoutSupport+Extensions.swift in Sources */, @@ -1904,6 +1923,7 @@ 5399969A2C27130000671340 /* ConstraintLayoutGuideDSL.swift in Sources */, 53014F922C11A8E80071CE39 /* ScannedItemRenderer.swift in Sources */, EC8A9B14254DC9D300F9AF99 /* LocalFileManager.swift in Sources */, + 67A2AF6E2C6B46D100039F30 /* ScanSessionPreviewViewController.swift in Sources */, 678809ED2C6A2ECB00EF9046 /* CompressType.swift in Sources */, 5399968A2C27130000671340 /* ConstraintMakerExtendable.swift in Sources */, 67A20DDD2C57A142009D2F25 /* DocumentLayout.swift in Sources */, diff --git a/MiniScanner/Modules/DocumentPreview/DocumentPreviewViewController.swift b/MiniScanner/Modules/DocumentPreview/DocumentPreviewViewController.swift index 1822e44..1b5039b 100644 --- a/MiniScanner/Modules/DocumentPreview/DocumentPreviewViewController.swift +++ b/MiniScanner/Modules/DocumentPreview/DocumentPreviewViewController.swift @@ -313,10 +313,9 @@ extension DocumentPreviewViewController { private func displayImagePreviewSheet(at index: Int) { - let previewController = PreviewImageViewController() + let previewController = ScanSessionPreviewViewController(scanSession: session, selectedIndex: index) - let image = session.scannedItems[index].newRenderedImage?.retrieveImage() - previewController.image = image + previewController.modalPresentationStyle = .fullScreen present(previewController, animated: true) } diff --git a/MiniScanner/Modules/DocumentPreview/ScanSessionPreview/ScanSessionPreviewViewController.swift b/MiniScanner/Modules/DocumentPreview/ScanSessionPreview/ScanSessionPreviewViewController.swift new file mode 100644 index 0000000..fec8255 --- /dev/null +++ b/MiniScanner/Modules/DocumentPreview/ScanSessionPreview/ScanSessionPreviewViewController.swift @@ -0,0 +1,171 @@ +// +// ScanSessionPreviewViewController.swift +// MiniScanner +// +// Created by Mustafa Merza on 8/13/24. +// Copyright © 2024 AppsNectar. All rights reserved. +// + +import UIKit + +class ScanSessionPreviewViewController: UIViewController { + + struct Constants { + static let cellIdentifier = String(describing: ScannedItemPreviewPagerViewCell.self) + } + + @IBOutlet weak var closeButton: UIButton! + + @IBOutlet private weak var pagerView: FSPagerView! + + @IBOutlet weak var currentPageLabel: UILabel! + @IBOutlet private weak var previousPageButton: UIButton! + @IBOutlet private weak var nextPageButton: UIButton! + + private var scanSession: ScanSession + private var selectedIndex: Int + private var currentPageIndex: Int = 0 + + init(scanSession: ScanSession, selectedIndex: Int) { + self.scanSession = scanSession + self.selectedIndex = selectedIndex + super.init(nibName: nil, bundle: nil) + } + + required init?(coder aDecoder: NSCoder) { + scanSession = .newSession() + fatalError("init(coder:) should not be called for this class") + } + + override func viewDidLoad() { + super.viewDidLoad() + setupUI() + } + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + + pagerView.scrollToItem(at: selectedIndex, animated: false) + + updateCurrentPageIndex(index: selectedIndex) + } +} + +extension ScanSessionPreviewViewController { + + private func dismiss() { + dismiss(animated: true) + } + + private func setupUI() { + + view.backgroundColor = .mainBackground + + closeButton.tintColor = .mainText + + nextPageButton.tintColor = .mainText + previousPageButton.tintColor = .mainText + + currentPageLabel.set(font: .regular(15)) + currentPageLabel.set(color: .mainText) + + currentPageLabel.layer.backgroundColor = UIColor.cellBackground.cgColor + currentPageLabel.layer.cornerRadius = 5 + + updateCurrentPageLabel() + + setupPagerView() + } + + private func updateCurrentPageIndex(index: Int) { + + currentPageIndex = index + + updateCurrentPageLabel() + } + + private func updateCurrentPageLabel() { + + currentPageLabel.set(text: "\(currentPageIndex + 1)/\(scanSession.scannedItems.count)") + + currentPageLabel.textAlignment = .center + + previousPageButton.isEnabled = currentPageIndex > 0 + nextPageButton.isEnabled = currentPageIndex < scanSession.itemsCount - 1 + } + + private func setupPagerView() { + + pagerView.register(ScannedItemPreviewPagerViewCell.self, forCellWithReuseIdentifier: Constants.cellIdentifier) + + pagerView.transformer = FSPagerViewTransformer(type: .linear) + + pagerView.decelerationDistance = FSPagerView.automaticDistance + + pagerView.interitemSpacing = 16 + + pagerView.dataSource = self + pagerView.delegate = self + + pagerView.backgroundColor = .clear + } +} + +extension ScanSessionPreviewViewController { + + @IBAction func closeTapped(_ sender: Any) { + dismiss() + } + + @IBAction func previousPageTapped(_ sender: UIButton) { + if currentPageIndex > 0 { + + pagerView.scrollToItem(at: currentPageIndex - 1, animated: true) + + updateCurrentPageIndex(index: currentPageIndex - 1) + } + } + + @IBAction func nextPageTapped(_ sender: UIButton) { + + if currentPageIndex < (scanSession.itemsCount - 1) { + + pagerView.scrollToItem(at: currentPageIndex + 1, animated: true) + + updateCurrentPageIndex(index: currentPageIndex + 1) + } + } +} + +extension ScanSessionPreviewViewController: FSPagerViewDataSource { + + func numberOfItems(in pagerView: FSPagerView) -> Int { + scanSession.itemsCount + } + + func pagerView(_ pagerView: FSPagerView, cellForItemAt index: Int) -> FSPagerViewCell { + + let cell = pagerView.dequeueReusableCell(withReuseIdentifier: Constants.cellIdentifier, at: index) as! ScannedItemPreviewPagerViewCell + + let scannedItem = scanSession.scannedItems[index] + + cell.configure(with: scannedItem) + + return cell + } + + func pagerView(_ pagerView: FSPagerView, willDisplay cell: FSPagerViewCell, forItemAt index: Int) { + + if let cell = cell as? ScannedItemPreviewPagerViewCell { + cell.resetZoomScale() + } + } +} + +extension ScanSessionPreviewViewController: FSPagerViewDelegate { + + func pagerViewWillEndDragging(_ pagerView: FSPagerView, targetIndex: Int) { + + updateCurrentPageIndex(index: targetIndex) + } +} diff --git a/MiniScanner/Modules/DocumentPreview/ScanSessionPreview/ScanSessionPreviewViewController.xib b/MiniScanner/Modules/DocumentPreview/ScanSessionPreview/ScanSessionPreviewViewController.xib new file mode 100644 index 0000000..50ea88c --- /dev/null +++ b/MiniScanner/Modules/DocumentPreview/ScanSessionPreview/ScanSessionPreviewViewController.xib @@ -0,0 +1,121 @@ +<?xml version="1.0" encoding="UTF-8"?> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="32700.99.1234" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> + <device id="retina6_12" orientation="portrait" appearance="light"/> + <dependencies> + <deployment identifier="iOS"/> + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22685"/> + <capability name="Image references" minToolsVersion="12.0"/> + <capability name="Named colors" minToolsVersion="9.0"/> + <capability name="Safe area layout guides" minToolsVersion="9.0"/> + <capability name="System colors in document resources" minToolsVersion="11.0"/> + <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> + </dependencies> + <objects> + <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="ScanSessionPreviewViewController" customModule="MiniScanner" customModuleProvider="target"> + <connections> + <outlet property="closeButton" destination="1GI-I3-mFB" id="Xj2-oN-n0t"/> + <outlet property="currentPageLabel" destination="jlb-jd-Tmi" id="rq0-jO-GAS"/> + <outlet property="nextPageButton" destination="ee4-fn-Pid" id="7HR-Ue-150"/> + <outlet property="pagerView" destination="8XH-NA-Xkf" id="Urw-LX-bWG"/> + <outlet property="previousPageButton" destination="npZ-zg-b7l" id="Ujs-I9-G4u"/> + <outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/> + </connections> + </placeholder> + <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/> + <view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="i5M-Pr-FkT"> + <rect key="frame" x="0.0" y="0.0" width="393" height="852"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <subviews> + <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="1GI-I3-mFB" userLabel="Close Button"> + <rect key="frame" x="330.66666666666669" y="59" width="46.333333333333314" height="34.333333333333343"/> + <state key="normal" title="Button"/> + <buttonConfiguration key="configuration" style="plain" image="xmark" catalog="system"/> + <connections> + <action selector="closeTapped:" destination="-1" eventType="touchUpInside" id="8j6-Lg-mA1"/> + </connections> + </button> + <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="8XH-NA-Xkf" customClass="FSPagerView" customModule="MiniScanner" customModuleProvider="target"> + <rect key="frame" x="0.0" y="109.33333333333331" width="393" height="628.66666666666674"/> + <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> + </view> + <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="N5h-2g-eCN" userLabel="Page Index View"> + <rect key="frame" x="113.33333333333333" y="758" width="166.33333333333337" height="40"/> + <subviews> + <stackView opaque="NO" contentMode="scaleToFill" distribution="fillProportionally" spacing="16" translatesAutoresizingMaskIntoConstraints="NO" id="6FS-gP-vAl"> + <rect key="frame" x="0.0" y="0.0" width="166.33333333333334" height="40"/> + <subviews> + <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="npZ-zg-b7l"> + <rect key="frame" x="0.0" y="0.0" width="40" height="40"/> + <constraints> + <constraint firstAttribute="width" constant="40" id="sNR-zM-pbj"/> + </constraints> + <color key="tintColor" name="Main Text"/> + <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/> + <state key="normal"> + <imageReference key="image" image="arrow.backward" catalog="system" symbolScale="large"/> + </state> + <connections> + <action selector="previousPageTapped:" destination="-1" eventType="touchUpInside" id="TJ7-Ve-8b1"/> + </connections> + </button> + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="1/4" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="jlb-jd-Tmi" userLabel="Current Page Label"> + <rect key="frame" x="56.000000000000014" y="0.0" width="54.333333333333329" height="40"/> + <fontDescription key="fontDescription" type="system" pointSize="17"/> + <nil key="textColor"/> + <nil key="highlightedColor"/> + </label> + <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ee4-fn-Pid"> + <rect key="frame" x="126.33333333333331" y="0.0" width="40" height="40"/> + <constraints> + <constraint firstAttribute="width" constant="40" id="Evf-Pb-5Kx"/> + </constraints> + <color key="tintColor" name="Main Text"/> + <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/> + <state key="normal"> + <color key="titleColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> + <imageReference key="image" image="arrow.forward" catalog="system" symbolScale="large"/> + </state> + <connections> + <action selector="nextPageTapped:" destination="-1" eventType="touchUpInside" id="bsh-lp-WHd"/> + </connections> + </button> + </subviews> + </stackView> + </subviews> + <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> + <constraints> + <constraint firstAttribute="bottom" secondItem="6FS-gP-vAl" secondAttribute="bottom" id="Kdf-Yt-cuz"/> + <constraint firstAttribute="height" constant="40" id="Qaj-se-6vP"/> + <constraint firstItem="6FS-gP-vAl" firstAttribute="leading" secondItem="N5h-2g-eCN" secondAttribute="leading" id="cxn-l2-bkT"/> + <constraint firstItem="6FS-gP-vAl" firstAttribute="top" secondItem="N5h-2g-eCN" secondAttribute="top" id="oz1-eu-afy"/> + <constraint firstAttribute="trailing" secondItem="6FS-gP-vAl" secondAttribute="trailing" id="qG4-gQ-kpq"/> + </constraints> + </view> + </subviews> + <viewLayoutGuide key="safeArea" id="fnl-2z-Ty3"/> + <color key="backgroundColor" systemColor="systemBackgroundColor"/> + <constraints> + <constraint firstItem="fnl-2z-Ty3" firstAttribute="trailing" secondItem="8XH-NA-Xkf" secondAttribute="trailing" id="9U6-ge-i6c"/> + <constraint firstItem="N5h-2g-eCN" firstAttribute="top" secondItem="8XH-NA-Xkf" secondAttribute="bottom" constant="20" id="NrL-vB-lek"/> + <constraint firstItem="fnl-2z-Ty3" firstAttribute="bottom" secondItem="N5h-2g-eCN" secondAttribute="bottom" constant="20" id="TE5-zn-iHA"/> + <constraint firstItem="8XH-NA-Xkf" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" id="UA3-27-nog"/> + <constraint firstItem="8XH-NA-Xkf" firstAttribute="top" secondItem="1GI-I3-mFB" secondAttribute="bottom" constant="16" id="YCo-nm-QRI"/> + <constraint firstItem="1GI-I3-mFB" firstAttribute="top" secondItem="fnl-2z-Ty3" secondAttribute="top" id="hxR-mn-zdh"/> + <constraint firstItem="fnl-2z-Ty3" firstAttribute="trailing" secondItem="1GI-I3-mFB" secondAttribute="trailing" constant="16" id="vef-4k-5rr"/> + <constraint firstItem="N5h-2g-eCN" firstAttribute="centerX" secondItem="fnl-2z-Ty3" secondAttribute="centerX" id="zD5-Lh-ZwB"/> + </constraints> + <point key="canvasLocation" x="-31.297709923664122" y="-11.267605633802818"/> + </view> + </objects> + <resources> + <image name="arrow.backward" catalog="system" width="128" height="95"/> + <image name="arrow.forward" catalog="system" width="128" height="95"/> + <image name="xmark" catalog="system" width="128" height="113"/> + <namedColor name="Main Text"> + <color red="0.31372549019607843" green="0.31372549019607843" blue="0.31372549019607843" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> + </namedColor> + <systemColor name="systemBackgroundColor"> + <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> + </systemColor> + </resources> +</document> diff --git a/MiniScanner/Modules/DocumentPreview/ScanSessionPreview/ScannedItemPreviewPagerViewCell.swift b/MiniScanner/Modules/DocumentPreview/ScanSessionPreview/ScannedItemPreviewPagerViewCell.swift new file mode 100644 index 0000000..c02282a --- /dev/null +++ b/MiniScanner/Modules/DocumentPreview/ScanSessionPreview/ScannedItemPreviewPagerViewCell.swift @@ -0,0 +1,69 @@ +// +// ScannedItemPreviewPagerViewCell.swift +// MiniScanner +// +// Created by Mustafa Merza on 8/13/24. +// Copyright © 2024 AppsNectar. All rights reserved. +// + +import Foundation + +class ScannedItemPreviewPagerViewCell: FSPagerViewCell { + + private lazy var scrollView: UIScrollView = { + + var width = contentView.frame.width + var height = contentView.frame.height + + var scrollView: UIScrollView = UIScrollView(frame: CGRect(x: 0, y: 0, width: width, height: height)) + scrollView.delegate = self + + scrollView.backgroundColor = .clear + + scrollView.alwaysBounceVertical = false + scrollView.alwaysBounceHorizontal = false + + scrollView.showsVerticalScrollIndicator = false + scrollView.showsHorizontalScrollIndicator = false + + scrollView.minimumZoomScale = 1.0 + scrollView.maximumZoomScale = 10.0 + + scrollView.addSubview(innerImageView) + + return scrollView + }() + + private lazy var innerImageView: UIImageView = { + + var width = contentView.frame.width + var height = contentView.frame.height + + var imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: width, height: height)) + + imageView.clipsToBounds = true + + imageView.contentMode = .scaleAspectFit + + return imageView + }() + + func configure(with scannedItem: ScannedItem) { + + innerImageView.image = scannedItem.newRenderedImage?.retrieveImage() + + contentView.addSubview(scrollView) + } + + func resetZoomScale() { + + scrollView.zoomScale = 1.0 + } +} + +extension ScannedItemPreviewPagerViewCell: UIScrollViewDelegate { + + func viewForZooming(in scrollView: UIScrollView) -> UIView? { + innerImageView + } +} diff --git a/MiniScanner/Modules/EditViewController/EditViewController.swift b/MiniScanner/Modules/EditViewController/EditViewController.swift index 07a1a4c..9444d8c 100644 --- a/MiniScanner/Modules/EditViewController/EditViewController.swift +++ b/MiniScanner/Modules/EditViewController/EditViewController.swift @@ -714,6 +714,15 @@ extension EditViewController { private func handleShareTypeChanged() { shareTypeLabel.set(localized: shareType.displayName) } + + private func displayImagePreviewSheet(at index: Int) { + + let previewController = ScanSessionPreviewViewController(scanSession: scanSession, selectedIndex: index) + + previewController.modalPresentationStyle = .fullScreen + + present(previewController, animated: true) + } } // MARK: - BannerViewDelegate @@ -756,11 +765,7 @@ extension EditViewController: BannerViewDelegate { } func preview(index: Int) { - let previewController = PreviewImageViewController() - if let image = scanSession.scannedItems[index].newRenderedImage?.retrieveImage() { - previewController.image = image - } - present(previewController, animated: true) + displayImagePreviewSheet(at: index) } func delete(index: Int) { -- GitLab