From cfe43c4af423265b362999118a18a8732686fcf6 Mon Sep 17 00:00:00 2001 From: Team Mobile Schorsch Date: Mon, 13 Feb 2023 12:52:13 +0000 Subject: [PATCH] Release version 3.0.0-beta04 --- Documentation/source/Customization guide.md | 22 ++-- Documentation/source/Features.md | 16 ++- Documentation/source/Getting started.md | 4 +- .../source/Migration to version 3.x.x.md | 14 +-- README.md | 4 +- .../Core/Custom views/BottomLabelButton.swift | 35 ++++-- .../Core/Custom views/ButtonsView.swift | 2 + .../ContainerNavigationController.swift | 1 - .../Extensions/UINavigationController.swift | 2 +- .../Core/GiniConfiguration.swift | 7 -- .../Core/Models/GiniCaptureDocument.swift | 6 +- .../Core/Models/GiniCaptureFont.swift | 6 +- .../Core/Models/GiniPDFDocument.swift | 15 ++- .../Analysis/AnalysisViewController.swift | 10 +- .../Core/Screens/Camera/Camera.swift | 14 +-- .../Camera2/Camera2ViewController.swift | 5 +- .../Views/CameraBottomNavigationBar.swift | 23 ++-- .../DocumentPickerCoordinator.swift | 15 +-- .../Gallery/AlbumsFooterView.swift | 2 +- .../Gallery/AlbumsHeaderView.swift | 2 +- .../Gallery/AlbumsPickerTableViewCell.swift | 12 +- .../Gallery/AlbumsPickerViewController.swift | 1 + .../ImagePickerCollectionViewCell.swift | 2 +- .../Error/ErrorScreenViewController.swift | 57 ++++++---- .../Onboarding/OnboardingDataSource.swift | 20 ++-- .../Onboarding/OnboardingViewController.swift | 48 +++----- .../Views/OnboardingBottomNavigationBar.swift | 28 +++-- .../Onboarding/Views/OnboardingPageCell.swift | 62 ++++++----- ...ustomReviewScreenBottomNavigationBar.swift | 89 --------------- ...viewScreenBottomNavigationBarAdapter.swift | 57 ---------- .../Screens/Review/ReviewCollectionCell.swift | 2 + .../Screens/Review/ReviewViewController.swift | 96 ++++++++++++---- .../GiniScreenAPICoordinator+Analysis.swift | 3 +- .../GiniCaptureSDKVersion.swift | 2 +- .../GiniNetworkingScreenAPICoordinator.swift | 12 +- .../Camera/CameraBottomNavigationBar.xib | 33 ++++-- .../Resources/Camera/CameraPhone.xib | 5 +- .../Contents.json | 0 .../Onboarding 1.pdf | Bin .../Onboarding.pdf | Bin .../OnboardingBottomNavigationBar.xib | 6 +- .../OnboardingScreen/OnboardingPageCell.xib | 104 +++++++++++------- .../OnboardingViewController.xib | 12 +- .../CustomReviewScreenBottomNavigationBar.xib | 60 ---------- .../ReviewBottomNavigationBar.xib | 10 +- .../Resources/de.lproj/Localizable.strings | 7 +- .../Resources/en.lproj/Localizable.strings | 9 +- .../GiniCaptureDocumentValidatorTests.swift | 8 +- .../GiniCaptureFontTests.swift | 24 ++-- .../GiniCaptureTestsHelper.swift | 6 +- 50 files changed, 454 insertions(+), 526 deletions(-) delete mode 100644 Sources/GiniCaptureSDK/Core/Screens/Review/CustomReviewScreenBottomNavigationBar.swift delete mode 100644 Sources/GiniCaptureSDK/Core/Screens/Review/CustomReviewScreenBottomNavigationBarAdapter.swift rename Sources/GiniCaptureSDK/Resources/GiniImages.xcassets/{onboardingGoodLightning.imageset => onboardingGoodLighting.imageset}/Contents.json (100%) rename Sources/GiniCaptureSDK/Resources/GiniImages.xcassets/{onboardingGoodLightning.imageset => onboardingGoodLighting.imageset}/Onboarding 1.pdf (100%) rename Sources/GiniCaptureSDK/Resources/GiniImages.xcassets/{onboardingGoodLightning.imageset => onboardingGoodLighting.imageset}/Onboarding.pdf (100%) delete mode 100644 Sources/GiniCaptureSDK/Resources/ReviewScreen/CustomReviewScreenBottomNavigationBar.xib diff --git a/Documentation/source/Customization guide.md b/Documentation/source/Customization guide.md index 020d5d8..24565d6 100644 --- a/Documentation/source/Customization guide.md +++ b/Documentation/source/Customization guide.md @@ -11,7 +11,7 @@ The Gini Capture SDK components can be customized either through the `GiniConfig - [Analysis screen](#analysis-screen) - [Help screens](#help-screens) - [No result screen](#no-result-screen) -- [Error screens](#error-screens) +- [Error screens](#error-screen) ## Colors @@ -101,7 +101,9 @@ To allow users toggle the camera flash pass `true` to `GiniConfiguration.shared. - Turn off flash by default: Flash is on by default, and you can turn it off by passing `false` to `GiniConfiguration.shared.flashOnByDefault`. -### Camera access TODO +### Camera access + + ### QR Code Scanning @@ -129,7 +131,9 @@ This feature enables the Gini Capture SDK to import documents from the camera sc Please find more information in the [Import PDFs and images guide](https://developer.gini.net/gini-mobile-ios/GiniCaptureSDK/import-pdfs-and-images-guide.html). -### Camera import error handling TODO +### Camera import error handling + + ## Review screen @@ -138,7 +142,7 @@ Please find more information in the [Import PDFs and images guide](https://devel You can show a custom loading indicator with custom animation support on the process button. Your custom loading indicator should implement `OnButtonLoadingIndicatorAdapter` interface and be passed to `GiniConfiguration.shared.onButtonLoadingIndicator`. -The example implementation is available [here](https://github.com/gini/gini-mobile-ios/blob/GiniCaptureSDK%3B3.0.0-beta03/BankSDK/GiniBankSDKExample/GiniBankSDKExample/CustomLoadingIndicator.swift#L36). +The example implementation is available [here](https://github.com/gini/gini-mobile-ios/blob/GiniCaptureSDK%3B3.0.0-beta04/BankSDK/GiniBankSDKExample/GiniBankSDKExample/CustomLoadingIndicator.swift#L36). ## Analysis screen @@ -147,7 +151,7 @@ The example implementation is available [here](https://github.com/gini/gini-mobi You can show a custom loading indicator with custom animation support. Your custom loading indicator should implement `CustomLoadingIndicatorAdapter` interface and be passed to `GiniConfiguration.shared.customLoadingIndicator`. -The example implementation is available [here](https://github.com/gini/gini-mobile-ios/blob/GiniCaptureSDK%3B3.0.0-beta03/BankSDK/GiniBankSDKExample/GiniBankSDKExample/CustomLoadingIndicator.swift). +The example implementation is available [here](https://github.com/gini/gini-mobile-ios/blob/GiniCaptureSDK%3B3.0.0-beta04/BankSDK/GiniBankSDKExample/GiniBankSDKExample/CustomLoadingIndicator.swift). ## Help screens @@ -169,9 +173,9 @@ The example implementation is availible [here](https://github.com/gini/gini-mobi You can also disable the supported formats help screen by passing `false` to `GiniConfiguration.shared.shouldShowSupportedFormatsScreen`. -## Gallery album screen TODO +## Gallery album screen - + ## No result screen @@ -183,10 +187,10 @@ For this you must to implement `GiniCaptureResultsDelegate.giniCaptureDidEnterMa You can show a bottom navigation bar by passing true to `GiniConfiguration.shared.bottomNavigationBarEnabled`. There is a default implementation, but you can also use your own by implementing the `NoResultBottomNavigationBarAdapter` interface and passing it to `GiniConfiguration.shared.noResultNavigationBarBottomAdapter`. -You can find more details [here](https://developer.gini.net/gini-mobile-ios/GiniCaptureSDK/3.0.0-beta03/features.html#no-result-screen-customization). +You can find more details [here](https://developer.gini.net/gini-mobile-ios/GiniCaptureSDK/3.0.0-beta04/features.html#no-result-screen-customization). ## Error screen -You can find more details [here](https://developer.gini.net/gini-mobile-ios/GiniCaptureSDK/3.0.0-beta03/features.html#error-screen-customization). +You can find more details [here](https://developer.gini.net/gini-mobile-ios/GiniCaptureSDK/3.0.0-beta04/features.html#error-screen-customization). diff --git a/Documentation/source/Features.md b/Documentation/source/Features.md index 3b2e4b1..2b44bad 100644 --- a/Documentation/source/Features.md +++ b/Documentation/source/Features.md @@ -107,7 +107,7 @@ The `Open with` feature allows importing of files from other apps via iOS `share Please find more information in the [Open with guide](https://developer.gini.net/gini-mobile-ios/GiniCaptureSDK/open-with-guide.html). -# Help screen Customization +# Help screen customization You can show your own help screens in the Gini Capture SDK. You can pass the title and view controller for each screen to the @@ -124,6 +124,20 @@ The example implementation is availible [here](https://github.com/gini/gini-mobi You can also disable the supported formats help screen by passing `false` to `GiniConfiguration.shared.shouldShowSupportedFormatsScreen`. +# Review screen customization + +You can show a custom loading indicator with custom animation support on the process button. +Your custom loading indicator should implement `OnButtonLoadingIndicatorAdapter` interface and be passed to `GiniConfiguration.shared.onButtonLoadingIndicator`. + +The example implementation is available [here](https://github.com/gini/gini-mobile-ios/blob/GiniCaptureSDK%3B3.0.0-beta04/BankSDK/GiniBankSDKExample/GiniBankSDKExample/CustomLoadingIndicator.swift#L36). + +# Analysis screen customization + +You can show a custom loading indicator with custom animation support. +Your custom loading indicator should implement `CustomLoadingIndicatorAdapter` interface and be passed to `GiniConfiguration.shared.customLoadingIndicator`. + +The example implementation is available [here](https://github.com/gini/gini-mobile-ios/blob/GiniCaptureSDK%3B3.0.0-beta04/BankSDK/GiniBankSDKExample/GiniBankSDKExample/CustomLoadingIndicator.swift). + # No result screen customization You can show custom back navigation button on bottom navigation bar. You can pass your custom `NoResultBottomNavigationBarAdapter` implementation to diff --git a/Documentation/source/Getting started.md b/Documentation/source/Getting started.md index 3e813de..58e0ad5 100644 --- a/Documentation/source/Getting started.md +++ b/Documentation/source/Getting started.md @@ -22,14 +22,14 @@ Once you have your Swift package set up, adding `GiniCaptureSDK` as a dependency ```swift dependencies: [ - .package(url: "https://github.com/gini/capture-sdk-ios.git", .exact("3.0.0-beta03")) + .package(url: "https://github.com/gini/capture-sdk-ios.git", .exact("3.0.0-beta04")) ] ``` In case that you want to use the certificate pinning in the library, add `GiniCaptureSDKPinning`: ```swift dependencies: [ - .package(url: "https://github.com/gini/capture-sdk-pinning-ios.git", .exact("3.0.0-beta03")) + .package(url: "https://github.com/gini/capture-sdk-pinning-ios.git", .exact("3.0.0-beta04")) ] ``` diff --git a/Documentation/source/Migration to version 3.x.x.md b/Documentation/source/Migration to version 3.x.x.md index 6168a44..1e93ded 100644 --- a/Documentation/source/Migration to version 3.x.x.md +++ b/Documentation/source/Migration to version 3.x.x.md @@ -52,11 +52,11 @@ The following steps will help you migrate to the new public API: * Handling the analysis results and receiving the extracted information (error or cancellation) can be handled though `GiniCaptureResultsDelegate` protocol implementation. * You can also provide your own networking by implementing the `GiniCaptureNetworkService` and `GiniCaptureResultsDelegate` protocols. Pass your instances to the `UIViewController` initialiser of GiniCapture as shown below. * Remove all code related to interacting with the SDK's specific view controllers. From now on the entry point is the `UIViewController` and customization happens through `GiniConfiguration` and via overriding of images and color resources. -* Use the new UI customization options and follow the [Customization guide](https://developer.gini.net/gini-mobile-ios/GiniCaptureSDK/3.0.0-beta03/customization-guide.html) to adapt the look of the new UI. +* Use the new UI customization options and follow the [Customization guide](https://developer.gini.net/gini-mobile-ios/GiniCaptureSDK/3.0.0-beta04/customization-guide.html) to adapt the look of the new UI. # Migrate from Screen API -The new public API is based on the Screen API, so you only need to use the new UI customization options and follow the [Customization guide](https://developer.gini.net/gini-mobile-ios/GiniCaptureSDK/3.0.0-beta03/customization-guide.html) to adapt the look of the new UI. +The new public API is based on the Screen API, so you only need to use the new UI customization options and follow the [Customization guide](https://developer.gini.net/gini-mobile-ios/GiniCaptureSDK/3.0.0-beta04/customization-guide.html) to adapt the look of the new UI. # Overview of New UI Customization Options @@ -130,7 +130,7 @@ customizations. Images and text are onboarding page specific and need to be customized for each page. -[here][https://developer.gini.net/gini-mobile-ios/GiniCaptureSDK/3.0.0-beta03/features.html#onboarding] and [here](https://www.figma.com/file/1985HMF83siAXmysSn3dC6/iOS-Gini-Capture-SDK-3.0.0-UI-Customisation?node-id=243%3A3305&t=6sAk7LGf1mi3zV9L-1). +[here][https://developer.gini.net/gini-mobile-ios/GiniCaptureSDK/3.0.0-beta04/features.html#onboarding] and [here](https://www.figma.com/file/1985HMF83siAXmysSn3dC6/iOS-Gini-Capture-SDK-3.0.0-UI-Customisation?node-id=243%3A3305&t=6sAk7LGf1mi3zV9L-1). ### Breaking Changes @@ -191,7 +191,7 @@ String keys changed: You can show a bottom navigation bar by passing true to `GiniConfiguration.shared.bottomNavigationBarEnabled`. There is a default implementation, but you can also use your own by implementing the `HelpBottomNavigationBarAdapter` interface and passing it to `GiniConfiguration.shared.helpNavigationBarBottomAdapter`. -You can find more details [here][https://developer.gini.net/gini-mobile-ios/GiniCaptureSDK/3.0.0-beta03/features.html#help-screen-customization] and [here](https://www.figma.com/file/1985HMF83siAXmysSn3dC6/iOS-Gini-Capture-SDK-3.0.0-UI-Customisation?node-id=141%3A2328&t=6sAk7LGf1mi3zV9L-1). +You can find more details [here][https://developer.gini.net/gini-mobile-ios/GiniCaptureSDK/3.0.0-beta04/features.html#help-screen-customization] and [here](https://www.figma.com/file/1985HMF83siAXmysSn3dC6/iOS-Gini-Capture-SDK-3.0.0-UI-Customisation?node-id=141%3A2328&t=6sAk7LGf1mi3zV9L-1). ## Analysis screen @@ -274,7 +274,7 @@ For this you must to implement `GiniCaptureResultsDelegate.giniCaptureDidEnterMa You can show a bottom navigation bar by passing true to `GiniConfiguration.shared.bottomNavigationBarEnabled`. There is a default implementation, but you can also use your own by implementing the `NoResultBottomNavigationBarAdapter` interface and passing it to `GiniConfiguration.shared.noResultNavigationBarBottomAdapter`. -You can find more details [here](https://www.figma.com/file/1985HMF83siAXmysSn3dC6/iOS-Gini-Capture-SDK-3.0.0-UI-Customisation?node-id=263%3A6989&t=7wXW9XyhTUcmp5sk-1) and [here](https://developer.gini.net/gini-mobile-ios/GiniCaptureSDK/3.0.0-beta03/customization-guide.html#no-result-screen). +You can find more details [here](https://www.figma.com/file/1985HMF83siAXmysSn3dC6/iOS-Gini-Capture-SDK-3.0.0-UI-Customisation?node-id=263%3A6989&t=7wXW9XyhTUcmp5sk-1) and [here](https://developer.gini.net/gini-mobile-ios/GiniCaptureSDK/3.0.0-beta04/customization-guide.html#no-result-screen). ## Error screen @@ -295,11 +295,11 @@ The new error screen gives options to retake photos or enter details manually an You can show a bottom navigation bar by passing true to `GiniConfiguration.shared.bottomNavigationBarEnabled`. There is a default implementation, but you can also use your own by implementing the `ErrorBottomNavigationBarAdapter` interface and passing it to `GiniConfiguration.shared.errorNavigationBarBottomAdapter`. -You can find more details [here](https://developer.gini.net/gini-mobile-ios/GiniCaptureSDK/3.0.0-beta03/customization-guide.html#error-screen). +You can find more details [here](https://developer.gini.net/gini-mobile-ios/GiniCaptureSDK/3.0.0-beta04/customization-guide.html#error-screen). #### Option to enter details manually You can show your own UI for data input if an error occured and the user clicks the "Enter manually" button on the error screen. For this you must to implement `GiniCaptureResultsDelegate.giniCaptureDidEnterManually() `. -You can find more details [here](https://developer.gini.net/gini-mobile-ios/GiniCaptureSDK/3.0.0-beta03/features.html#error-screen-customization) and [here]((https://developer.gini.net/gini-mobile-ios/GiniCaptureSDK/3.0.0-beta03/customization-guide.html#error-screen). +You can find more details [here](https://developer.gini.net/gini-mobile-ios/GiniCaptureSDK/3.0.0-beta04/features.html#error-screen-customization) and [here]((https://developer.gini.net/gini-mobile-ios/GiniCaptureSDK/3.0.0-beta04/customization-guide.html#error-screen). diff --git a/README.md b/README.md index e8f301b..546cbd9 100644 --- a/README.md +++ b/README.md @@ -29,13 +29,13 @@ To inject your API credentials into the Example app, just add to the Example dir ## Requirements -- iOS 11+ +- iOS 12+ - Xcode 12+ **Note:** In order to have better analysis results it is highly recommended to enable only devices with 8MP camera and flash. These devices would be: -* iPhones with iOS 11 or higher. +* iPhones with iOS 12 or higher. * iPad Pro devices (iPad Air 2 and iPad Mini 4 have 8MP camera but no flash). ## Author diff --git a/Sources/GiniCaptureSDK/Core/Custom views/BottomLabelButton.swift b/Sources/GiniCaptureSDK/Core/Custom views/BottomLabelButton.swift index 7f53c09..5da19f2 100644 --- a/Sources/GiniCaptureSDK/Core/Custom views/BottomLabelButton.swift +++ b/Sources/GiniCaptureSDK/Core/Custom views/BottomLabelButton.swift @@ -37,18 +37,27 @@ final class BottomLabelButton: UIView { return image }() + private lazy var contentView: UIView = { + let contentView = UIView() + contentView.translatesAutoresizingMaskIntoConstraints = false + + return contentView + }() + init() { super.init(frame: .zero) - addSubview(actionLabel) - addSubview(iconView) + addSubview(contentView) + contentView.addSubview(actionLabel) + contentView.addSubview(iconView) addSubview(actionButton) setupConstraints() } required init?(coder aDecoder: NSCoder) { super.init(frame: .zero) - addSubview(actionLabel) - addSubview(iconView) + addSubview(contentView) + contentView.addSubview(actionLabel) + contentView.addSubview(iconView) addSubview(actionButton) } @@ -69,15 +78,21 @@ final class BottomLabelButton: UIView { actionButton.trailingAnchor.constraint(equalTo: trailingAnchor), actionButton.leadingAnchor.constraint(equalTo: leadingAnchor), - iconView.centerYAnchor.constraint(equalTo: centerYAnchor, constant: -10), - iconView.leadingAnchor.constraint(equalTo: leadingAnchor), - iconView.trailingAnchor.constraint(equalTo: trailingAnchor), + contentView.topAnchor.constraint(greaterThanOrEqualTo: topAnchor, constant: 5), + contentView.bottomAnchor.constraint(lessThanOrEqualTo: bottomAnchor, constant: -5), + contentView.centerYAnchor.constraint(equalTo: centerYAnchor), + contentView.trailingAnchor.constraint(equalTo: trailingAnchor), + contentView.leadingAnchor.constraint(equalTo: leadingAnchor), + + iconView.topAnchor.constraint(equalTo: contentView.topAnchor), + iconView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor), + iconView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor), iconView.heightAnchor.constraint(equalToConstant: 20), actionLabel.topAnchor.constraint(equalTo: iconView.bottomAnchor, constant: 5), - actionLabel.leadingAnchor.constraint(equalTo: leadingAnchor), - actionLabel.trailingAnchor.constraint(equalTo: trailingAnchor), - actionLabel.bottomAnchor.constraint(lessThanOrEqualTo: bottomAnchor, constant: 0) + actionLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor), + actionLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor), + actionLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor) ]) } diff --git a/Sources/GiniCaptureSDK/Core/Custom views/ButtonsView.swift b/Sources/GiniCaptureSDK/Core/Custom views/ButtonsView.swift index 66e8588..bffcdd8 100644 --- a/Sources/GiniCaptureSDK/Core/Custom views/ButtonsView.swift +++ b/Sources/GiniCaptureSDK/Core/Custom views/ButtonsView.swift @@ -13,6 +13,7 @@ class ButtonsView: UIView { let button = MultilineTitleButton() button.translatesAutoresizingMaskIntoConstraints = false button.setTitle(firstButtonTitle, for: .normal) + button.accessibilityLabel = firstButtonTitle return button }() @@ -20,6 +21,7 @@ class ButtonsView: UIView { let button = MultilineTitleButton() button.translatesAutoresizingMaskIntoConstraints = false button.setTitle(secondButtonTitle, for: .normal) + button.accessibilityLabel = secondButtonTitle return button }() diff --git a/Sources/GiniCaptureSDK/Core/Custom views/ContainerNavigationController.swift b/Sources/GiniCaptureSDK/Core/Custom views/ContainerNavigationController.swift index ba1bd5d..c8f9df2 100644 --- a/Sources/GiniCaptureSDK/Core/Custom views/ContainerNavigationController.swift +++ b/Sources/GiniCaptureSDK/Core/Custom views/ContainerNavigationController.swift @@ -37,7 +37,6 @@ final class ContainerNavigationController: UIViewController { self.rootViewController = rootViewController self.coordinator = parent self.giniConfiguration = giniConfiguration - setStatusBarStyle(to: giniConfiguration.statusBarStyle) super.init(nibName: nil, bundle: nil) } diff --git a/Sources/GiniCaptureSDK/Core/Extensions/UINavigationController.swift b/Sources/GiniCaptureSDK/Core/Extensions/UINavigationController.swift index 66bfa57..09b7416 100644 --- a/Sources/GiniCaptureSDK/Core/Extensions/UINavigationController.swift +++ b/Sources/GiniCaptureSDK/Core/Extensions/UINavigationController.swift @@ -12,7 +12,7 @@ extension UINavigationController { public func applyStyle(withConfiguration configuration: GiniConfiguration) { let titleTextAttrubutes = [NSAttributedString.Key.font: configuration.textStyleFonts[.bodyBold] as Any, NSAttributedString.Key.foregroundColor: GiniColor(light: UIColor.GiniCapture.dark1, dark: UIColor.GiniCapture.light1).uiColor()] - let navigationBackgroundColor = GiniColor(light: UIColor.GiniCapture.light1, dark: UIColor.GiniCapture.dark2).uiColor() + let navigationBackgroundColor = GiniColor(light: UIColor.GiniCapture.light2, dark: UIColor.GiniCapture.dark2).uiColor() if #available(iOS 13.0, *) { let appearance = UINavigationBarAppearance() appearance.configureWithOpaqueBackground() diff --git a/Sources/GiniCaptureSDK/Core/GiniConfiguration.swift b/Sources/GiniCaptureSDK/Core/GiniConfiguration.swift index 9f5cff1..1ff7fac 100644 --- a/Sources/GiniCaptureSDK/Core/GiniConfiguration.swift +++ b/Sources/GiniCaptureSDK/Core/GiniConfiguration.swift @@ -432,13 +432,6 @@ import GiniBankAPILibrary */ @objc public var shouldShowDragAndDropTutorial = true - // MARK: Albums screen - - /** - Sets the text color for the select more photos button on the albums screen. - */ - @objc public var albumsScreenSelectMorePhotosTextColor = GiniColor(light: Colors.Gini.blue, dark: Colors.Gini.blue) - /** Set an array of additional custom help menu items . Those items will be presented as table view cells on the help menu screen. By selecting the cell the user will be redirected to the page, which represented by viewController provided by customer during the `HelpMenuViewController.Item` initialization. */ diff --git a/Sources/GiniCaptureSDK/Core/Models/GiniCaptureDocument.swift b/Sources/GiniCaptureSDK/Core/Models/GiniCaptureDocument.swift index 77657ce..1885dfe 100644 --- a/Sources/GiniCaptureSDK/Core/Models/GiniCaptureDocument.swift +++ b/Sources/GiniCaptureSDK/Core/Models/GiniCaptureDocument.swift @@ -72,9 +72,9 @@ public class GiniCaptureDocumentBuilder: NSObject { - Returns: A `GiniCaptureDocument` if `data` has a valid type or `nil` if it hasn't. */ - public func build(with data: Data) -> GiniCaptureDocument? { + public func build(with data: Data, fileName: String?) -> GiniCaptureDocument? { if data.isPDF { - return GiniPDFDocument(data: data) + return GiniPDFDocument(data: data, fileName: fileName) } else if data.isImage { return GiniImageDocument(data: data, imageSource: documentSource, @@ -100,7 +100,7 @@ public class GiniCaptureDocumentBuilder: NSObject { return } - completion(self.build(with: data)) + completion(self.build(with: data, fileName: openURL.lastPathComponent)) } } } diff --git a/Sources/GiniCaptureSDK/Core/Models/GiniCaptureFont.swift b/Sources/GiniCaptureSDK/Core/Models/GiniCaptureFont.swift index 73841c2..94a231e 100644 --- a/Sources/GiniCaptureSDK/Core/Models/GiniCaptureFont.swift +++ b/Sources/GiniCaptureSDK/Core/Models/GiniCaptureFont.swift @@ -38,11 +38,7 @@ public class GiniCaptureFont: NSObject { } public func with(weight: UIFont.Weight, size: CGFloat, style: UIFont.TextStyle) -> UIFont { - if #available(iOS 11.0, *) { - return UIFontMetrics(forTextStyle: style).scaledFont(for: font(for: weight).withSize(size)) - } else { - return font(for: weight).withSize(size) - } + return UIFontMetrics(forTextStyle: style).scaledFont(for: font(for: weight).withSize(size)) } private func font(for weight: UIFont.Weight) -> UIFont { diff --git a/Sources/GiniCaptureSDK/Core/Models/GiniPDFDocument.swift b/Sources/GiniCaptureSDK/Core/Models/GiniPDFDocument.swift index 1c022d3..0a1b4a4 100644 --- a/Sources/GiniCaptureSDK/Core/Models/GiniPDFDocument.swift +++ b/Sources/GiniCaptureSDK/Core/Models/GiniPDFDocument.swift @@ -27,20 +27,27 @@ final public class GiniPDFDocument: NSObject, GiniCaptureDocument { Initializes a GiniPDFDocument with a preview image (from the first page) - Parameter data: PDF data + - Parameter fileName: PDF file name */ - init(data: Data) { + init(data: Data, fileName: String?) { self.data = data self.isReviewable = false self.id = UUID().uuidString self.isImported = true super.init() - + if let dataProvider = CGDataProvider(data: data as CFData), let pdfDocument = CGPDFDocument(dataProvider) { self.numberPages = pdfDocument.numberOfPages self.previewImage = renderFirstPage(fromPdf: pdfDocument) - self.pdfTitle = getKey("Title", from: pdfDocument) + + if let fileName = fileName { + self.pdfTitle = fileName + } else { + self.pdfTitle = getKey("Title", from: pdfDocument) + } + } } @@ -114,7 +121,7 @@ extension GiniPDFDocument: NSItemProviderReading { } static public func object(withItemProviderData data: Data, typeIdentifier: String) throws -> Self { - return self.init(data: data) + return self.init(data: data, fileName: nil) } } diff --git a/Sources/GiniCaptureSDK/Core/Screens/Analysis/AnalysisViewController.swift b/Sources/GiniCaptureSDK/Core/Screens/Analysis/AnalysisViewController.swift index 0fb665c..eaac10f 100644 --- a/Sources/GiniCaptureSDK/Core/Screens/Analysis/AnalysisViewController.swift +++ b/Sources/GiniCaptureSDK/Core/Screens/Analysis/AnalysisViewController.swift @@ -25,11 +25,10 @@ import UIKit /** In case that the `GiniCaptureDocument` analysed is an image it will display a no results screen - with some capture suggestions. It won't show any screen if it is not an image, return `false` in that case. - - - returns: `true` if the screen was shown or `false` if it wasn't. + with some capture suggestions. + */ - func tryDisplayNoResultsScreen() -> Bool + func tryDisplayNoResultsScreen() } /** @@ -234,7 +233,8 @@ import UIKit NSLayoutConstraint.activate([ loadingIndicatorText.topAnchor.constraint(equalTo: loadingIndicator.bottomAnchor, constant: 16), loadingIndicatorText.leadingAnchor.constraint(equalTo: imageView.leadingAnchor), - loadingIndicatorText.centerXAnchor.constraint(equalTo: imageView.centerXAnchor)]) + loadingIndicatorText.centerXAnchor.constraint(equalTo: imageView.centerXAnchor), + loadingIndicatorText.bottomAnchor.constraint(lessThanOrEqualTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -16)]) } private func addLoadingView(intoContainer container: UIView? = nil) { diff --git a/Sources/GiniCaptureSDK/Core/Screens/Camera/Camera.swift b/Sources/GiniCaptureSDK/Core/Screens/Camera/Camera.swift index 1bde9a9..5606ab2 100644 --- a/Sources/GiniCaptureSDK/Core/Screens/Camera/Camera.swift +++ b/Sources/GiniCaptureSDK/Core/Screens/Camera/Camera.swift @@ -201,15 +201,11 @@ final class Camera: NSObject, CameraProtocol { fileprivate extension Camera { var captureSettings: AVCapturePhotoSettings { - var captureSettings: AVCapturePhotoSettings - if #available(iOS 11.0, *) { - captureSettings = AVCapturePhotoSettings(rawPixelFormatType: 0, - rawFileType: nil, - processedFormat: nil, - processedFileType: AVFileType.jpg) - } else { - captureSettings = AVCapturePhotoSettings() - } + var captureSettings = AVCapturePhotoSettings(rawPixelFormatType: 0, + rawFileType: nil, + processedFormat: nil, + processedFileType: AVFileType.jpg) + guard let device = self.videoDeviceInput?.device else { return captureSettings } #if !targetEnvironment(simulator) diff --git a/Sources/GiniCaptureSDK/Core/Screens/Camera/Camera2/Camera2ViewController.swift b/Sources/GiniCaptureSDK/Core/Screens/Camera/Camera2/Camera2ViewController.swift index eb71bba..2afc8f1 100644 --- a/Sources/GiniCaptureSDK/Core/Screens/Camera/Camera2/Camera2ViewController.swift +++ b/Sources/GiniCaptureSDK/Core/Screens/Camera/Camera2/Camera2ViewController.swift @@ -78,9 +78,12 @@ public final class Camera2ViewController: UIViewController, CameraScreen { setupView() } + public override var preferredStatusBarStyle: UIStatusBarStyle { + return giniConfiguration.statusBarStyle + } + public override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) - setStatusBarStyle(to: giniConfiguration.statusBarStyle) cameraPane.toggleCaptureButtonActivation(state: true) } diff --git a/Sources/GiniCaptureSDK/Core/Screens/Camera/Views/CameraBottomNavigationBar.swift b/Sources/GiniCaptureSDK/Core/Screens/Camera/Views/CameraBottomNavigationBar.swift index 660e556..c902ee9 100644 --- a/Sources/GiniCaptureSDK/Core/Screens/Camera/Views/CameraBottomNavigationBar.swift +++ b/Sources/GiniCaptureSDK/Core/Screens/Camera/Views/CameraBottomNavigationBar.swift @@ -20,15 +20,22 @@ class CameraBottomNavigationBar: UIView { func setupView() { let configuration = GiniConfiguration.shared let textColor = UIColor.GiniCapture.accent1 - rightButton.setTitle(NSLocalizedStringPreferredFormat( - "ginicapture.navigationbar.camera.help", - comment: "Camera Help Button"), for: .normal) - rightButton.titleLabel?.font = configuration.textStyleFonts[.body] - rightButton.setTitleColor(textColor, for: .normal) + let font = configuration.textStyleFonts[.body] ?? UIFont.systemFont(ofSize: 20) + let rightButtonTitle = NSLocalizedStringPreferredFormat("ginicapture.navigationbar.camera.help", + comment: "Camera Help Button") + let rightAttributedString = NSAttributedString(string: rightButtonTitle, + attributes: [NSAttributedString.Key.font: font, + NSAttributedString.Key.foregroundColor: textColor]) + rightButton.setAttributedTitle(rightAttributedString, for: .normal) rightButton.tintColor = GiniColor(light: UIColor.GiniCapture.dark1, dark: UIColor.GiniCapture.light1).uiColor() - leftButton.setTitle(NSLocalizedStringPreferredFormat("ginicapture.navigationbar.analysis.backToReview", - comment: "Review screen title"), for: .normal) - leftButton.setTitleColor(textColor, for: .normal) + + let leftButtonTitle = NSLocalizedStringPreferredFormat("ginicapture.navigationbar.analysis.backToReview", + comment: "Review screen title") + let leftAttributedString = NSAttributedString(string: leftButtonTitle, + attributes: [NSAttributedString.Key.font: font, + NSAttributedString.Key.foregroundColor: textColor]) + leftButton.setAttributedTitle(leftAttributedString, for: .normal) + if #available(iOS 15.0, *) { leftButton.configuration?.imagePadding = 4 } else { diff --git a/Sources/GiniCaptureSDK/Core/Screens/Document picker/DocumentPickerCoordinator.swift b/Sources/GiniCaptureSDK/Core/Screens/Document picker/DocumentPickerCoordinator.swift index f71d067..3ebaa05 100644 --- a/Sources/GiniCaptureSDK/Core/Screens/Document picker/DocumentPickerCoordinator.swift +++ b/Sources/GiniCaptureSDK/Core/Screens/Document picker/DocumentPickerCoordinator.swift @@ -227,24 +227,25 @@ public final class DocumentPickerCoordinator: NSObject { // MARK: - Fileprivate methods fileprivate extension DocumentPickerCoordinator { - func createDocument(fromData data: Data) -> GiniCaptureDocument? { + func createDocument(fromData dataDictionary: (Data?, String?)) -> GiniCaptureDocument? { + guard let data = dataDictionary.0 else { return nil } let documentBuilder = GiniCaptureDocumentBuilder(documentSource: .external) documentBuilder.importMethod = .picker - return documentBuilder.build(with: data) + return documentBuilder.build(with: data, fileName: dataDictionary.1) } - func data(fromUrl url: URL) -> Data? { + func data(fromUrl url: URL) -> (Data?, String?) { do { _ = url.startAccessingSecurityScopedResource() let data = try Data(contentsOf: url) url.stopAccessingSecurityScopedResource() - return data + return (data, url.lastPathComponent) } catch { url.stopAccessingSecurityScopedResource() } - return nil + return (nil, nil) } func saveCurrentNavBarAppearance() { @@ -325,7 +326,7 @@ extension DocumentPickerCoordinator: UIDocumentPickerDelegate { return } - if #available(iOS 11.0, *), giniConfiguration.documentPickerNavigationBarTintColor != nil { + if #available(iOS 12.0, *), giniConfiguration.documentPickerNavigationBarTintColor != nil { restoreSavedNavBarAppearance() } @@ -337,7 +338,7 @@ extension DocumentPickerCoordinator: UIDocumentPickerDelegate { } public func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) { - if #available(iOS 11.0, *), giniConfiguration.documentPickerNavigationBarTintColor != nil { + if #available(iOS 12.0, *), giniConfiguration.documentPickerNavigationBarTintColor != nil { restoreSavedNavBarAppearance() } diff --git a/Sources/GiniCaptureSDK/Core/Screens/Document picker/Gallery/AlbumsFooterView.swift b/Sources/GiniCaptureSDK/Core/Screens/Document picker/Gallery/AlbumsFooterView.swift index 168207e..59c73ef 100644 --- a/Sources/GiniCaptureSDK/Core/Screens/Document picker/Gallery/AlbumsFooterView.swift +++ b/Sources/GiniCaptureSDK/Core/Screens/Document picker/Gallery/AlbumsFooterView.swift @@ -15,7 +15,7 @@ final class AlbumsFooterView: UIView { let configuration = GiniConfiguration.shared label.text = NSLocalizedStringPreferredFormat("ginicapture.albums.footer", comment: "Albums footer message") - label.font = configuration.customFont.with(weight: .regular, size: 14, style: .footnote) + label.font = configuration.textStyleFonts[.footnote] label.textColor = GiniColor(light: .GiniCapture.dark1, dark: .GiniCapture.light1).uiColor() label.textAlignment = .center label.lineBreakMode = .byWordWrapping diff --git a/Sources/GiniCaptureSDK/Core/Screens/Document picker/Gallery/AlbumsHeaderView.swift b/Sources/GiniCaptureSDK/Core/Screens/Document picker/Gallery/AlbumsHeaderView.swift index 34f30d3..29887a8 100644 --- a/Sources/GiniCaptureSDK/Core/Screens/Document picker/Gallery/AlbumsHeaderView.swift +++ b/Sources/GiniCaptureSDK/Core/Screens/Document picker/Gallery/AlbumsHeaderView.swift @@ -19,7 +19,7 @@ final class AlbumsHeaderView: UITableViewHeaderFooterView { let configuration = GiniConfiguration.shared let buttonTitle = NSLocalizedStringPreferredFormat("ginicapture.albums.selectMorePhotosButton", comment: "Title for select more photos button") - selectPhotosButton.titleLabel?.font = configuration.customFont.with(weight: .regular, size: 16, style: .footnote) + selectPhotosButton.titleLabel?.font = configuration.textStyleFonts[.footnote] selectPhotosButton.setTitle(buttonTitle, for: .normal) selectPhotosButton.setTitleColor(.GiniCapture.accent1, for: .normal) selectPhotosButton.sizeToFit() diff --git a/Sources/GiniCaptureSDK/Core/Screens/Document picker/Gallery/AlbumsPickerTableViewCell.swift b/Sources/GiniCaptureSDK/Core/Screens/Document picker/Gallery/AlbumsPickerTableViewCell.swift index 1e1a4e8..a16bef2 100644 --- a/Sources/GiniCaptureSDK/Core/Screens/Document picker/Gallery/AlbumsPickerTableViewCell.swift +++ b/Sources/GiniCaptureSDK/Core/Screens/Document picker/Gallery/AlbumsPickerTableViewCell.swift @@ -31,7 +31,7 @@ final class AlbumsPickerTableViewCell: UITableViewCell { lazy var albumTitleLabel: UILabel = { let albumTitle = UILabel(frame: .zero) albumTitle.translatesAutoresizingMaskIntoConstraints = false - + albumTitle.textColor = GiniColor(light: .GiniCapture.dark1, dark: .GiniCapture.light1).uiColor() return albumTitle }() @@ -39,11 +39,7 @@ final class AlbumsPickerTableViewCell: UITableViewCell { let albumSubTitle = UILabel(frame: .zero) albumSubTitle.translatesAutoresizingMaskIntoConstraints = false - if #available(iOS 13.0, *) { - albumSubTitle.textColor = .secondaryLabel - } else { - albumSubTitle.textColor = .lightGray - } + albumSubTitle.textColor = GiniColor(light: .GiniCapture.dark6, dark: .GiniCapture.light6).uiColor() return albumSubTitle }() @@ -94,8 +90,8 @@ final class AlbumsPickerTableViewCell: UITableViewCell { func setUp(with album: Album, giniConfiguration: GiniConfiguration, galleryManager: GalleryManagerProtocol) { albumTitleLabel.text = album.title albumSubTitleLabel.text = "\(album.count)" - albumTitleLabel.font = giniConfiguration.customFont.with(weight: .regular, size: 16, style: .headline) - albumSubTitleLabel.font = giniConfiguration.customFont.with(weight: .regular, size: 12, style: .subheadline) + albumTitleLabel.font = giniConfiguration.textStyleFonts[.headline] + albumSubTitleLabel.font = giniConfiguration.textStyleFonts[.subheadline] let asset = album.assets[album.assets.count - 1] galleryManager.fetchImage(from: asset, diff --git a/Sources/GiniCaptureSDK/Core/Screens/Document picker/Gallery/AlbumsPickerViewController.swift b/Sources/GiniCaptureSDK/Core/Screens/Document picker/Gallery/AlbumsPickerViewController.swift index a960cd5..0a682fe 100644 --- a/Sources/GiniCaptureSDK/Core/Screens/Document picker/Gallery/AlbumsPickerViewController.swift +++ b/Sources/GiniCaptureSDK/Core/Screens/Document picker/Gallery/AlbumsPickerViewController.swift @@ -42,6 +42,7 @@ final class AlbumsPickerViewController: UIViewController, PHPhotoLibraryChangeOb forCellReuseIdentifier: AlbumsPickerTableViewCell.identifier) tableView.layer.cornerRadius = Constants.cornerRadius tableView.contentInset = UIEdgeInsets(top: Constants.padding, left: 0, bottom: Constants.padding, right: 0) + tableView.separatorColor = GiniColor(light: .GiniCapture.light4, dark: .GiniCapture.dark6).uiColor() return tableView }() diff --git a/Sources/GiniCaptureSDK/Core/Screens/Document picker/Gallery/ImagePickerCollectionViewCell.swift b/Sources/GiniCaptureSDK/Core/Screens/Document picker/Gallery/ImagePickerCollectionViewCell.swift index 99333ac..41393d3 100644 --- a/Sources/GiniCaptureSDK/Core/Screens/Document picker/Gallery/ImagePickerCollectionViewCell.swift +++ b/Sources/GiniCaptureSDK/Core/Screens/Document picker/Gallery/ImagePickerCollectionViewCell.swift @@ -50,7 +50,7 @@ final class ImagePickerCollectionViewCell: UICollectionViewCell { circleView.translatesAutoresizingMaskIntoConstraints = false circleView.layer.borderWidth = 1 circleView.layer.cornerRadius = self.selectedCircleSize.width / 2 - circleView.layer.borderColor = UIColor.white.cgColor + circleView.layer.borderColor = UIColor.GiniCapture.light1.cgColor return circleView }() diff --git a/Sources/GiniCaptureSDK/Core/Screens/Error/ErrorScreenViewController.swift b/Sources/GiniCaptureSDK/Core/Screens/Error/ErrorScreenViewController.swift index 2cf0faa..33a5761 100644 --- a/Sources/GiniCaptureSDK/Core/Screens/Error/ErrorScreenViewController.swift +++ b/Sources/GiniCaptureSDK/Core/Screens/Error/ErrorScreenViewController.swift @@ -40,9 +40,18 @@ class ErrorScreenViewController: UIViewController { let label = UILabel() label.translatesAutoresizingMaskIntoConstraints = false label.numberOfLines = 0 + label.isAccessibilityElement = true return label }() + private lazy var scrollView: UIScrollView = { + let scrollView = UIScrollView() + scrollView.showsVerticalScrollIndicator = false + scrollView.showsHorizontalScrollIndicator = false + scrollView.translatesAutoresizingMaskIntoConstraints = false + return scrollView + }() + let viewModel: BottomButtonsViewModel private let errorType: ErrorType private let documentType: GiniCaptureDocumentType @@ -95,7 +104,8 @@ class ErrorScreenViewController: UIViewController { configureErrorContent() view.backgroundColor = GiniColor(light: UIColor.GiniCapture.light2, dark: UIColor.GiniCapture.dark2).uiColor() view.addSubview(errorHeader) - view.addSubview(errorContent) + view.addSubview(scrollView) + scrollView.addSubview(errorContent) buttonsView.translatesAutoresizingMaskIntoConstraints = false view.addSubview(buttonsView) configureButtons() @@ -225,14 +235,20 @@ class ErrorScreenViewController: UIViewController { } buttonsHeightConstraint = buttonsConstraint NSLayoutConstraint.activate([ + scrollView.topAnchor.constraint(equalTo: errorHeader.bottomAnchor), + scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor), + scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor), + scrollView.bottomAnchor.constraint(equalTo: buttonsView.topAnchor), + errorHeader.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), errorHeader.leadingAnchor.constraint(equalTo: view.leadingAnchor), errorHeader.trailingAnchor.constraint(equalTo: view.trailingAnchor), errorHeader.heightAnchor.constraint( greaterThanOrEqualToConstant: Constants.errorHeaderMinHeight.rawValue), - errorContent.topAnchor.constraint( - equalTo: errorHeader.bottomAnchor, - constant: Constants.errorContentBottomMargin.rawValue), + errorHeader.heightAnchor.constraint( + lessThanOrEqualToConstant: Constants.errorHeaderMaxHeight.rawValue), + errorContent.topAnchor.constraint(equalTo: scrollView.topAnchor, + constant: Constants.errorContentBottomMargin.rawValue), buttonsConstraint ]) configureHorizontalConstraints() @@ -243,26 +259,24 @@ class ErrorScreenViewController: UIViewController { if UIDevice.current.isIpad { NSLayoutConstraint.activate([ errorContent.centerXAnchor.constraint(equalTo: view.centerXAnchor), - errorContent.widthAnchor.constraint( - equalTo: view.widthAnchor, - multiplier: Constants.iPadWidthMultiplier.rawValue), - buttonsView.leadingAnchor.constraint( - equalTo: view.leadingAnchor, - constant: GiniMargins.margin), - buttonsView.trailingAnchor.constraint( - equalTo: view.trailingAnchor, - constant: -GiniMargins.margin) + errorContent.widthAnchor.constraint(equalTo: view.widthAnchor, + multiplier: Constants.iPadWidthMultiplier.rawValue), + buttonsView.leadingAnchor.constraint(equalTo: view.leadingAnchor, + constant: GiniMargins.margin), + buttonsView.trailingAnchor.constraint(equalTo: view.trailingAnchor, + constant: -GiniMargins.margin) ]) } else { NSLayoutConstraint.activate([ - errorContent.leadingAnchor.constraint( - equalTo: view.leadingAnchor, - constant: Constants.textContentMargin.rawValue), - errorContent.trailingAnchor.constraint( - equalTo: view.trailingAnchor, - constant: -Constants.textContentMargin.rawValue), - buttonsView.leadingAnchor.constraint(equalTo: errorContent.leadingAnchor), - buttonsView.trailingAnchor.constraint(equalTo: errorContent.trailingAnchor) + errorContent.leadingAnchor.constraint(equalTo: view.leadingAnchor, + constant: Constants.textContentMargin.rawValue), + errorContent.trailingAnchor.constraint(equalTo: view.trailingAnchor, + constant: -Constants.textContentMargin.rawValue), + errorContent.bottomAnchor.constraint(greaterThanOrEqualTo: scrollView.bottomAnchor), + buttonsView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor, + constant: GiniMargins.margin), + buttonsView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor, + constant: -GiniMargins.margin) ]) } } @@ -273,6 +287,7 @@ class ErrorScreenViewController: UIViewController { case textContentMargin = 24 case iPadButtonsWidth = 280 case errorHeaderMinHeight = 64 + case errorHeaderMaxHeight = 180 case errorContentBottomMargin = 13 case iPadWidthMultiplier = 0.7 } diff --git a/Sources/GiniCaptureSDK/Core/Screens/Onboarding/OnboardingDataSource.swift b/Sources/GiniCaptureSDK/Core/Screens/Onboarding/OnboardingDataSource.swift index 396e16c..020b506 100644 --- a/Sources/GiniCaptureSDK/Core/Screens/Onboarding/OnboardingDataSource.swift +++ b/Sources/GiniCaptureSDK/Core/Screens/Onboarding/OnboardingDataSource.swift @@ -22,7 +22,7 @@ protocol OnboardingScreen: AnyObject { class OnboardingDataSource: NSObject, BaseCollectionViewDataSource { private enum OnboadingPageType: Int { case alignCorners = 0 - case lightning = 1 + case lighting = 1 case multipage = 2 case qrcode = 3 } @@ -42,11 +42,11 @@ class OnboardingDataSource: NSObject, BaseCollectionViewDataSource { comment: "onboarding flat paper title"), description: NSLocalizedStringPreferredFormat( "ginicapture.onboarding.flatPaper.description", comment: "onboarding flat paper description")), - OnboardingPage(imageName: "onboardingGoodLightning", title: NSLocalizedStringPreferredFormat( - "ginicapture.onboarding.goodLightning.title", - comment: "onboarding good lightning title"), description: NSLocalizedStringPreferredFormat( - "ginicapture.onboarding.goodLightning.description", - comment: "onboarding good lightning description")) + OnboardingPage(imageName: "onboardingGoodLighting", title: NSLocalizedStringPreferredFormat( + "ginicapture.onboarding.goodLighting.title", + comment: "onboarding good lighting title"), description: NSLocalizedStringPreferredFormat( + "ginicapture.onboarding.goodLighting.description", + comment: "onboarding good lighting description")) ] if giniConfiguration.multipageEnabled { sections.append( @@ -78,7 +78,7 @@ class OnboardingDataSource: NSObject, BaseCollectionViewDataSource { adapters = [ .alignCorners: giniConfiguration.onboardingAlignCornersIllustrationAdapter, - .lightning: giniConfiguration.onboardingLightingIllustrationAdapter, + .lighting: giniConfiguration.onboardingLightingIllustrationAdapter, .multipage: giniConfiguration.onboardingMultiPageIllustrationAdapter, .qrcode: giniConfiguration.onboardingQRCodeIllustrationAdapter ] @@ -102,8 +102,10 @@ class OnboardingDataSource: NSObject, BaseCollectionViewDataSource { } cell.iconView.setupView() - cell.fullText.text = item.description - cell.title.text = item.title + cell.descriptionLabel.text = item.description + cell.descriptionLabel.accessibilityValue = item.description + cell.titleLabel.text = item.title + cell.titleLabel.accessibilityValue = item.title } func collectionView(_ collectionView: UICollectionView, diff --git a/Sources/GiniCaptureSDK/Core/Screens/Onboarding/OnboardingViewController.swift b/Sources/GiniCaptureSDK/Core/Screens/Onboarding/OnboardingViewController.swift index b489101..c71f457 100644 --- a/Sources/GiniCaptureSDK/Core/Screens/Onboarding/OnboardingViewController.swift +++ b/Sources/GiniCaptureSDK/Core/Screens/Onboarding/OnboardingViewController.swift @@ -44,19 +44,15 @@ class OnboardingViewController: UIViewController { } private func configurePageControl() { - pageControl.pageIndicatorTintColor = GiniColor( - light: UIColor.GiniCapture.dark1, - dark: UIColor.GiniCapture.light1 - ).uiColor().withAlphaComponent(0.3) - pageControl.currentPageIndicatorTintColor = GiniColor( - light: UIColor.GiniCapture.dark1, - dark: UIColor.GiniCapture.light1 - ).uiColor() - pageControl.addTarget( - self, - action: #selector(self.pageControlSelectionAction(_:)), - for: .valueChanged) + pageControl.pageIndicatorTintColor = GiniColor(light: UIColor.GiniCapture.dark1, + dark: UIColor.GiniCapture.light1 + ).uiColor().withAlphaComponent(0.3) + pageControl.currentPageIndicatorTintColor = GiniColor(light: UIColor.GiniCapture.dark1, + dark: UIColor.GiniCapture.light1 + ).uiColor() + pageControl.addTarget(self, action: #selector(self.pageControlSelectionAction(_:)), for: .valueChanged) pageControl.numberOfPages = dataSource.itemSections.count + pageControl.isAccessibilityElement = true } private func setupView() { @@ -87,12 +83,10 @@ class OnboardingViewController: UIViewController { } private func configureBasicNavigation() { - nextButton.layer.cornerRadius = 14 - nextButton.setTitle("Next", for: .normal) - nextButton.backgroundColor = GiniColor( - light: UIColor.GiniCapture.accent1, - dark: UIColor.GiniCapture.accent1 - ).uiColor() + nextButton.titleLabel?.font = configuration.textStyleFonts[.bodyBold] + nextButton.accessibilityValue = NSLocalizedStringPreferredFormat("ginicapture.onboarding.next", + comment: "Next button") + nextButton.configure(with: GiniConfiguration.shared.primaryButtonConfiguration) nextButton.addTarget(self, action: #selector(nextPage), for: .touchUpInside) navigationItem.rightBarButtonItem = skipButton } @@ -122,21 +116,12 @@ class OnboardingViewController: UIViewController { bottomNavigationBar = navigationBar view.addSubview(navigationBar) layoutBottomNavigationBar(navigationBar) - navigationBarBottomAdapter?.showButtons( - navigationButtons: [.skip, .next], - navigationBar: navigationBar) - nextButton.layer.cornerRadius = 14 + navigationBarBottomAdapter?.showButtons(navigationButtons: [.skip, .next], navigationBar: navigationBar) + nextButton.setTitle(NSLocalizedStringPreferredFormat( "ginicapture.onboarding.next", comment: "Next button"), for: .normal) - nextButton.backgroundColor = GiniColor( - light: UIColor.GiniCapture.accent1, - dark: UIColor.GiniCapture.accent1 - ).uiColor() - nextButton.titleLabel?.textColor = GiniColor( - light: UIColor.GiniCapture.light1, - dark: UIColor.GiniCapture.light1 - ).uiColor() + nextButton.addTarget(self, action: #selector(nextPage), for: .touchUpInside) navigationItem.rightBarButtonItem = skipButton } @@ -194,6 +179,9 @@ extension OnboardingViewController: OnboardingScreen { nextButton.setTitle(NSLocalizedStringPreferredFormat( "ginicapture.onboarding.getstarted", comment: "Get Started button"), for: .normal) + nextButton.accessibilityValue = NSLocalizedStringPreferredFormat( + "ginicapture.onboarding.getstarted", + comment: "Get Started button") } } default: diff --git a/Sources/GiniCaptureSDK/Core/Screens/Onboarding/Views/OnboardingBottomNavigationBar.swift b/Sources/GiniCaptureSDK/Core/Screens/Onboarding/Views/OnboardingBottomNavigationBar.swift index e621790..d346187 100644 --- a/Sources/GiniCaptureSDK/Core/Screens/Onboarding/Views/OnboardingBottomNavigationBar.swift +++ b/Sources/GiniCaptureSDK/Core/Screens/Onboarding/Views/OnboardingBottomNavigationBar.swift @@ -29,21 +29,29 @@ final class OnboardingBottomNavigationBar: UIView { nextButton.titleLabel?.font = configuration.textStyleFonts[.bodyBold] nextButton.configure(with: configuration.primaryButtonConfiguration) + nextButton.isAccessibilityElement = true skipButton.titleLabel?.font = configuration.textStyleFonts[.bodyBold] skipButton.configure(with: configuration.transparentButtonConfiguration) + skipButton.isAccessibilityElement = true getStarted.titleLabel?.font = configuration.textStyleFonts[.bodyBold] getStarted.configure(with: configuration.primaryButtonConfiguration) - - skipButton.setTitle(NSLocalizedStringPreferredFormat( - "ginicapture.onboarding.skip", - comment: "Skip button"), for: .normal) - nextButton.setTitle(NSLocalizedStringPreferredFormat( - "ginicapture.onboarding.next", - comment: "Next button"), for: .normal) - getStarted.setTitle(NSLocalizedStringPreferredFormat( - "ginicapture.onboarding.getstarted", - comment: "Get Started button"), for: .normal) + getStarted.isAccessibilityElement = true + + skipButton.setTitle(NSLocalizedStringPreferredFormat("ginicapture.onboarding.skip", + comment: "Skip button"), for: .normal) + skipButton.accessibilityValue = NSLocalizedStringPreferredFormat("ginicapture.onboarding.skip", + comment: "Skip button") + + nextButton.setTitle(NSLocalizedStringPreferredFormat("ginicapture.onboarding.next", + comment: "Next button"), for: .normal) + nextButton.accessibilityValue = NSLocalizedStringPreferredFormat("ginicapture.onboarding.next", + comment: "Next button") + + getStarted.setTitle(NSLocalizedStringPreferredFormat("ginicapture.onboarding.getstarted", + comment: "Get Started button"), for: .normal) + getStarted.accessibilityValue = NSLocalizedStringPreferredFormat("ginicapture.onboarding.getstarted", + comment: "Get Started button") } } diff --git a/Sources/GiniCaptureSDK/Core/Screens/Onboarding/Views/OnboardingPageCell.swift b/Sources/GiniCaptureSDK/Core/Screens/Onboarding/Views/OnboardingPageCell.swift index 884683b..67f8a3e 100644 --- a/Sources/GiniCaptureSDK/Core/Screens/Onboarding/Views/OnboardingPageCell.swift +++ b/Sources/GiniCaptureSDK/Core/Screens/Onboarding/Views/OnboardingPageCell.swift @@ -10,55 +10,50 @@ import UIKit class OnboardingPageCell: UICollectionViewCell { @IBOutlet weak var iconView: OnboardingImageView! - @IBOutlet weak var title: UILabel! - @IBOutlet weak var fullText: UILabel! + @IBOutlet weak var titleLabel: UILabel! + @IBOutlet weak var descriptionLabel: UILabel! + @IBOutlet weak var iconBottomConstraint: NSLayoutConstraint! @IBOutlet weak var topConstraint: NSLayoutConstraint! - @IBOutlet weak var iconMargin: NSLayoutConstraint! - - private enum Constants: CGFloat { - case topMargin = 85 - case topIPadMargin = 150 - case iconMargin = 30 - case maxIconMargin = 58 - } - override func awakeFromNib() { super.awakeFromNib() setupView() } private func setupView() { - title.textColor = GiniColor( - light: UIColor.GiniCapture.dark1, - dark: UIColor.GiniCapture.light1 - ).uiColor() - fullText.textColor = GiniColor( - light: UIColor.GiniCapture.dark6, - dark: UIColor.GiniCapture.dark7 - ).uiColor() + titleLabel.textColor = GiniColor(light: UIColor.GiniCapture.dark1, + dark: UIColor.GiniCapture.light1).uiColor() + titleLabel.font = GiniConfiguration.shared.textStyleFonts[.title2Bold] + titleLabel.isAccessibilityElement = true + + descriptionLabel.textColor = GiniColor(light: UIColor.GiniCapture.dark6, + dark: UIColor.GiniCapture.dark7).uiColor() + descriptionLabel.font = GiniConfiguration.shared.textStyleFonts[.title2Bold] + descriptionLabel.isAccessibilityElement = true + } private func calculateIconMargin() -> CGFloat { let largestHeightDiff: CGFloat = 265 // 932 PRO MAX - 667 SE let scaleFactor = (UIScreen.main.bounds.size.height - 667) / largestHeightDiff - let diff = Constants.maxIconMargin.rawValue - Constants.iconMargin.rawValue - return Constants.iconMargin.rawValue + diff * min(scaleFactor, 1) + let diff = Constants.maxIconPadding - Constants.iconPadding + + return Constants.iconPadding + diff * min(scaleFactor, 1) } override func layoutSubviews() { if UIDevice.current.isIpad { if UIApplication.shared.statusBarOrientation.isLandscape { - topConstraint.constant = Constants.topMargin.rawValue - iconMargin.constant = calculateIconMargin() + topConstraint.constant = Constants.compactTopPadding + iconBottomConstraint.constant = calculateIconMargin() } else { - topConstraint.constant = Constants.topIPadMargin.rawValue - iconMargin.constant = Constants.maxIconMargin.rawValue + topConstraint.constant = Constants.regularTopPadding + iconBottomConstraint.constant = Constants.maxIconPadding } } else { - topConstraint.constant = Constants.topMargin.rawValue - iconMargin.constant = calculateIconMargin() + topConstraint.constant = Constants.compactTopPadding + iconBottomConstraint.constant = calculateIconMargin() } super.layoutSubviews() } @@ -72,7 +67,16 @@ class OnboardingPageCell: UICollectionViewCell { iconView.illustrationAdapter = nil iconView.icon = nil iconView.subviews.forEach({ $0.removeFromSuperview() }) - title.text = "" - fullText.text = "" + titleLabel.text = "" + descriptionLabel.text = "" + } +} + +private extension OnboardingPageCell { + enum Constants { + static let compactTopPadding: CGFloat = 85 + static let regularTopPadding: CGFloat = 150 + static let iconPadding: CGFloat = 30 + static let maxIconPadding: CGFloat = 58 } } diff --git a/Sources/GiniCaptureSDK/Core/Screens/Review/CustomReviewScreenBottomNavigationBar.swift b/Sources/GiniCaptureSDK/Core/Screens/Review/CustomReviewScreenBottomNavigationBar.swift deleted file mode 100644 index 01e0663..0000000 --- a/Sources/GiniCaptureSDK/Core/Screens/Review/CustomReviewScreenBottomNavigationBar.swift +++ /dev/null @@ -1,89 +0,0 @@ -// -// CustomReviewScreenBottomNavigationBar.swift -// -// -// Created by David Vizaknai on 07.11.2022. -// - -import UIKit - -protocol CustomReviewScreenBottomNavigationBarDelegate: AnyObject { - func didTapMainButton(on navigationBar: CustomReviewScreenBottomNavigationBar) - func didTapSecondaryButton(on navigationBar: CustomReviewScreenBottomNavigationBar) -} - -final class CustomReviewScreenBottomNavigationBar: UIView { - - @IBOutlet weak var mainButton: UIButton! - @IBOutlet weak var secondaryButton: UIButton! - - weak var delegate: CustomReviewScreenBottomNavigationBarDelegate? - - private var loadingIndicatorView: UIActivityIndicatorView = { - let indicatorView = UIActivityIndicatorView() - indicatorView.hidesWhenStopped = true - indicatorView.style = .whiteLarge - indicatorView.color = .white - return indicatorView - }() - - private let configuration = GiniConfiguration.shared - - override func awakeFromNib() { - super.awakeFromNib() - - setupView() - } - - private func setupView() { - mainButton.addTarget(self, action: #selector(mainButtonClicked), for: .touchUpInside) - secondaryButton.addTarget(self, action: #selector(secondaryButtonClicked), for: .touchUpInside) - addLoadingView() - } - - func set(loadingState isLoading: Bool) { - if self.configuration.multipageEnabled { - if !isLoading { - self.mainButton.alpha = 1 - self.mainButton.isEnabled = true - self.hideAnimation() - return - } - - self.mainButton.alpha = 0.3 - self.mainButton.isEnabled = false - self.showAnimation() - } - } - - private func addLoadingView() { - loadingIndicatorView.translatesAutoresizingMaskIntoConstraints = false - addSubview(loadingIndicatorView) - bringSubviewToFront(loadingIndicatorView) - - NSLayoutConstraint.activate([ - loadingIndicatorView.centerXAnchor.constraint(equalTo: mainButton.centerXAnchor), - loadingIndicatorView.centerYAnchor.constraint(equalTo: mainButton.centerYAnchor), - loadingIndicatorView.widthAnchor.constraint(equalToConstant: 45), - loadingIndicatorView.heightAnchor.constraint(equalToConstant: 45) - ]) - } - - private func showAnimation() { - loadingIndicatorView.startAnimating() - } - - private func hideAnimation() { - loadingIndicatorView.stopAnimating() - } - - @objc - private func mainButtonClicked() { - delegate?.didTapMainButton(on: self) - } - - @objc - private func secondaryButtonClicked() { - delegate?.didTapSecondaryButton(on: self) - } -} diff --git a/Sources/GiniCaptureSDK/Core/Screens/Review/CustomReviewScreenBottomNavigationBarAdapter.swift b/Sources/GiniCaptureSDK/Core/Screens/Review/CustomReviewScreenBottomNavigationBarAdapter.swift deleted file mode 100644 index db63016..0000000 --- a/Sources/GiniCaptureSDK/Core/Screens/Review/CustomReviewScreenBottomNavigationBarAdapter.swift +++ /dev/null @@ -1,57 +0,0 @@ -// -// CustomReviewScreenBottomNavigationBarAdapter.swift -// -// -// Created by David Vizaknai on 07.11.2022. -// - -import UIKit - -final public class CustomReviewScreenBottomNavigationBarAdapter: ReviewScreenBottomNavigationBarAdapter { - private var mainButtonCallback: (() -> Void)? - private var secondaryButtonCallback: (() -> Void)? - var view: CustomReviewScreenBottomNavigationBar? - - public init() {} - - public func setMainButtonClickedActionCallback(_ callback: @escaping () -> Void) { - mainButtonCallback = callback - } - - public func setSecondaryButtonClickedActionCallback(_ callback: @escaping () -> Void) { - secondaryButtonCallback = callback - } - - public func setMainButtonTitle(with title: String) { - view?.mainButton.setTitle(title, for: .normal) - } - - public func set(loadingState isLoading: Bool) { - view?.set(loadingState: isLoading) - } - - public func injectedView() -> UIView { - if let navigationBarView = CustomReviewScreenBottomNavigationBar().loadNib() - as? CustomReviewScreenBottomNavigationBar { - self.view = navigationBarView - self.view?.delegate = self - return navigationBarView - } else { - return UIView() - } - } - - public func onDeinit() { - - } -} - -extension CustomReviewScreenBottomNavigationBarAdapter: CustomReviewScreenBottomNavigationBarDelegate { - func didTapMainButton(on navigationBar: CustomReviewScreenBottomNavigationBar) { - mainButtonCallback?() - } - - func didTapSecondaryButton(on navigationBar: CustomReviewScreenBottomNavigationBar) { - secondaryButtonCallback?() - } -} diff --git a/Sources/GiniCaptureSDK/Core/Screens/Review/ReviewCollectionCell.swift b/Sources/GiniCaptureSDK/Core/Screens/Review/ReviewCollectionCell.swift index 8efe4bc..8e96849 100644 --- a/Sources/GiniCaptureSDK/Core/Screens/Review/ReviewCollectionCell.swift +++ b/Sources/GiniCaptureSDK/Core/Screens/Review/ReviewCollectionCell.swift @@ -34,6 +34,8 @@ final class ReviewCollectionCell: UICollectionViewCell { button.imageView?.contentMode = .scaleAspectFit button.addTarget(self, action: #selector(didTapDelete), for: .touchUpInside) button.isHidden = true + button.isAccessibilityElement = true + button.accessibilityLabel = NSLocalizedStringPreferredFormat("ginicapture.review.delete", comment: "Delete") return button }() diff --git a/Sources/GiniCaptureSDK/Core/Screens/Review/ReviewViewController.swift b/Sources/GiniCaptureSDK/Core/Screens/Review/ReviewViewController.swift index 06295d9..3a86db3 100644 --- a/Sources/GiniCaptureSDK/Core/Screens/Review/ReviewViewController.swift +++ b/Sources/GiniCaptureSDK/Core/Screens/Review/ReviewViewController.swift @@ -84,6 +84,20 @@ public final class ReviewViewController: UIViewController { // MARK: - UI initialization + private lazy var scrollView: UIScrollView = { + let scrollView = UIScrollView() + scrollView.showsVerticalScrollIndicator = false + scrollView.showsHorizontalScrollIndicator = false + scrollView.translatesAutoresizingMaskIntoConstraints = false + return scrollView + }() + + private lazy var contentView: UIView = { + let contentView = UIView() + contentView.translatesAutoresizingMaskIntoConstraints = false + return contentView + }() + lazy var collectionView: UICollectionView = { let layout = UICollectionViewFlowLayout() layout.scrollDirection = .horizontal @@ -138,6 +152,7 @@ public final class ReviewViewController: UIViewController { pageControl.currentPageIndicatorTintColor = GiniColor(light: UIColor.GiniCapture.dark1, dark: UIColor.GiniCapture.light1).uiColor() pageControl.translatesAutoresizingMaskIntoConstraints = false + pageControl.isAccessibilityElement = true pageControl.addTarget(self, action: #selector(pageControlTapHandler(sender:)), for: .touchUpInside) return pageControl @@ -151,6 +166,9 @@ public final class ReviewViewController: UIViewController { button.setTitle(NSLocalizedStringPreferredFormat("ginicapture.multipagereview.mainButtonTitle", comment: "Process button title"), for: .normal) button.addTarget(self, action: #selector(didTapProcessDocument), for: .touchUpInside) + button.isAccessibilityElement = true + button.accessibilityLabel = NSLocalizedStringPreferredFormat("ginicapture.multipagereview.mainButtonTitle", + comment: "Process button title") return button }() @@ -169,6 +187,10 @@ public final class ReviewViewController: UIViewController { self.setCellStatus(for: self.currentPage, isActive: false) self.delegate?.reviewDidTapAddImage(self) } + addPagesButton.isAccessibilityElement = true + addPagesButton.accessibilityLabel = NSLocalizedStringPreferredFormat( + "ginicapture.multipagereview.secondaryButtonTitle", + comment: "Add pages button title") return addPagesButton }() @@ -204,29 +226,45 @@ public final class ReviewViewController: UIViewController { // MARK: - Constraints + private lazy var scrollViewConstraints: [NSLayoutConstraint] = [ + scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), + scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor), + scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor), + scrollView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor) + ] + + private lazy var contenViewConstraints: [NSLayoutConstraint] = [ + contentView.topAnchor.constraint(equalTo: scrollView.topAnchor), + contentView.leadingAnchor.constraint(equalTo: view.leadingAnchor), + contentView.trailingAnchor.constraint(equalTo: view.trailingAnchor), + contentView.heightAnchor.constraint(greaterThanOrEqualTo: scrollView.heightAnchor), + contentView.bottomAnchor.constraint(greaterThanOrEqualTo: scrollView.bottomAnchor) + ] + private lazy var tipLabelConstraints: [NSLayoutConstraint] = [ - tipLabel.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: Constants.padding), - tipLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor), - tipLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor), - tipLabel.heightAnchor.constraint(equalToConstant: Constants.titleHeight)] + tipLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: Constants.padding), + tipLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor), + tipLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor), + tipLabel.heightAnchor.constraint(greaterThanOrEqualToConstant: Constants.titleHeight), + tipLabel.heightAnchor.constraint(lessThanOrEqualToConstant: Constants.maxTitleHeight)] private lazy var collectionViewConstraints: [NSLayoutConstraint] = [ collectionView.topAnchor.constraint(equalTo: tipLabel.bottomAnchor, constant: Constants.padding), - collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor), - collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor), + collectionView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor), + collectionView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor), collectionViewHeightConstraint] private lazy var pageControlConstraints: [NSLayoutConstraint] = [ pageControl.topAnchor.constraint(equalTo: collectionView.bottomAnchor, constant: Constants.padding * 2), - pageControl.leadingAnchor.constraint(equalTo: view.leadingAnchor), - pageControl.trailingAnchor.constraint(equalTo: view.trailingAnchor)] + pageControl.leadingAnchor.constraint(equalTo: contentView.leadingAnchor), + pageControl.trailingAnchor.constraint(equalTo: contentView.trailingAnchor)] private lazy var processButtonConstraints: [NSLayoutConstraint] = [ processButton.topAnchor.constraint(equalTo: buttonContainer.topAnchor), - processButton.widthAnchor.constraint(equalToConstant: Constants.buttonSize.width), + processButton.widthAnchor.constraint(greaterThanOrEqualToConstant: Constants.buttonSize.width), processButton.leadingAnchor.constraint(equalTo: buttonContainer.leadingAnchor), - processButton.heightAnchor.constraint(equalToConstant: Constants.buttonSize.height), - processButton.bottomAnchor.constraint(equalTo: buttonContainer.bottomAnchor), + processButton.heightAnchor.constraint(greaterThanOrEqualToConstant: Constants.buttonSize.height), + processButton.bottomAnchor.constraint(equalTo: buttonContainer.bottomAnchor, constant: -8), processButton.trailingAnchor.constraint(lessThanOrEqualTo: buttonContainer.trailingAnchor)] private lazy var addPagesButtonConstraints: [NSLayoutConstraint] = [ @@ -237,9 +275,10 @@ public final class ReviewViewController: UIViewController { private lazy var buttonContainerConstraints: [NSLayoutConstraint] = [ buttonContainer.topAnchor.constraint(equalTo: pageControl.bottomAnchor, constant: Constants.padding * 2), - buttonContainer.centerXAnchor.constraint(equalTo: view.centerXAnchor), - buttonContainer.bottomAnchor.constraint(greaterThanOrEqualTo: view.safeAreaLayoutGuide.bottomAnchor, - constant: -Constants.bottomPadding) + buttonContainer.centerXAnchor.constraint(equalTo: contentView.centerXAnchor), + buttonContainer.bottomAnchor.constraint(lessThanOrEqualTo: contentView.bottomAnchor, + constant: -Constants.bottomPadding), + buttonContainer.leadingAnchor.constraint(greaterThanOrEqualTo: view.leadingAnchor) ] // MARK: - Init @@ -299,7 +338,7 @@ extension ReviewViewController { navigationBar.bottomAnchor.constraint(equalTo: view.bottomAnchor), navigationBar.leadingAnchor.constraint(equalTo: view.leadingAnchor), navigationBar.trailingAnchor.constraint(equalTo: view.trailingAnchor), - navigationBar.heightAnchor.constraint(equalToConstant: 114) + navigationBar.heightAnchor.constraint(equalToConstant: Constants.bottomNavigationBarHeight) ]) view.bringSubviewToFront(navigationBar) view.layoutSubviews() @@ -366,11 +405,14 @@ extension ReviewViewController { title = NSLocalizedStringPreferredFormat("ginicapture.multipagereview.title", comment: "Screen title") view.backgroundColor = GiniColor(light: UIColor.GiniCapture.light2, dark: UIColor.GiniCapture.dark2).uiColor() - view.addSubview(tipLabel) - view.addSubview(collectionView) - view.addSubview(pageControl) + + view.addSubview(scrollView) + scrollView.addSubview(contentView) + contentView.addSubview(tipLabel) + contentView.addSubview(collectionView) + contentView.addSubview(pageControl) if !giniConfiguration.bottomNavigationBarEnabled { - view.addSubview(buttonContainer) + contentView.addSubview(buttonContainer) buttonContainer.addSubview(processButton) if giniConfiguration.multipageEnabled { buttonContainer.addSubview(addPagesButton) @@ -472,6 +514,8 @@ extension ReviewViewController { private func addConstraints() { collectionViewHeightConstraint.priority = .defaultLow + NSLayoutConstraint.activate(scrollViewConstraints) + NSLayoutConstraint.activate(contenViewConstraints) NSLayoutConstraint.activate(tipLabelConstraints) NSLayoutConstraint.activate(collectionViewConstraints) NSLayoutConstraint.activate(pageControlConstraints) @@ -484,7 +528,7 @@ extension ReviewViewController { } } else { NSLayoutConstraint.activate([ - pageControl.bottomAnchor.constraint(equalTo: view.bottomAnchor, + pageControl.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -Constants.pageControlBottomPadding), collectionView.bottomAnchor.constraint(greaterThanOrEqualTo: pageControl.topAnchor, constant: -Constants.padding * 2) @@ -531,7 +575,11 @@ extension ReviewViewController { private func calculatedCellSize() -> CGSize { let a4Ratio = 1.4142 if UIDevice.current.isIpad { - let height = self.view.bounds.height - 260 + var height = self.view.bounds.height - 260 + if giniConfiguration.bottomNavigationBarEnabled { + height -= Constants.bottomNavigationBarHeight + height -= Constants.padding + } let width = height / a4Ratio return CGSize(width: width, height: height) } else { @@ -632,7 +680,9 @@ extension ReviewViewController: UICollectionViewDelegateFlowLayout { } private func setCellStatus(for index: Int, isActive: Bool) { - let cell = collectionView.cellForItem(at: IndexPath(row: index, section: 0)) as? ReviewCollectionCell + let indexToSet = min(index, pages.count - 1) + + let cell = collectionView.cellForItem(at: IndexPath(row: indexToSet, section: 0)) as? ReviewCollectionCell cell?.isActive = isActive } } @@ -657,5 +707,7 @@ extension ReviewViewController { static let pageControlBottomPadding: CGFloat = 130 static let buttonSize: CGSize = CGSize(width: 126, height: 50) static let titleHeight: CGFloat = 18 + static let maxTitleHeight: CGFloat = 100 + static let bottomNavigationBarHeight: CGFloat = 114 } } diff --git a/Sources/GiniCaptureSDK/Core/Screens/Screen API Coordinator/GiniScreenAPICoordinator+Analysis.swift b/Sources/GiniCaptureSDK/Core/Screens/Screen API Coordinator/GiniScreenAPICoordinator+Analysis.swift index 8e8c049..c90dee4 100644 --- a/Sources/GiniCaptureSDK/Core/Screens/Screen API Coordinator/GiniScreenAPICoordinator+Analysis.swift +++ b/Sources/GiniCaptureSDK/Core/Screens/Screen API Coordinator/GiniScreenAPICoordinator+Analysis.swift @@ -141,7 +141,7 @@ extension GiniScreenAPICoordinator: AnalysisDelegate { screenAPINavigationController.pushViewController(viewController, animated: animated) } - public func tryDisplayNoResultsScreen() -> Bool { + public func tryDisplayNoResultsScreen() { var shouldDisplay = false var noResultType: NoResultScreenViewController.NoResultType? switch pages.type { @@ -163,6 +163,5 @@ extension GiniScreenAPICoordinator: AnalysisDelegate { noResultsScreen, animated: true) } } - return shouldDisplay } } diff --git a/Sources/GiniCaptureSDK/GiniCaptureSDKVersion.swift b/Sources/GiniCaptureSDK/GiniCaptureSDKVersion.swift index fd9d98f..9b4f823 100644 --- a/Sources/GiniCaptureSDK/GiniCaptureSDKVersion.swift +++ b/Sources/GiniCaptureSDK/GiniCaptureSDKVersion.swift @@ -5,4 +5,4 @@ // Created by Nadya Karaban on 29.10.21. // -public let GiniCaptureSDKVersion = "3.0.0-beta03" +public let GiniCaptureSDKVersion = "3.0.0-beta04" diff --git a/Sources/GiniCaptureSDK/Networking/GiniNetworkingScreenAPICoordinator.swift b/Sources/GiniCaptureSDK/Networking/GiniNetworkingScreenAPICoordinator.swift index 2414d2b..8f9bbb0 100644 --- a/Sources/GiniCaptureSDK/Networking/GiniNetworkingScreenAPICoordinator.swift +++ b/Sources/GiniCaptureSDK/Networking/GiniNetworkingScreenAPICoordinator.swift @@ -19,14 +19,7 @@ import GiniBankAPILibrary - parameter result: Contains the analysis result */ func giniCaptureAnalysisDidFinishWith(result: AnalysisResult) - - /** - Called when the analysis finished without results. - - - parameter showingNoResultsScreen: Indicated if the `ImageAnalysisNoResultsViewController` has been shown - */ - func giniCaptureAnalysisDidFinishWithoutResults(_ showingNoResultsScreen: Bool) - + /** Called when the analysis was cancelled. */ @@ -129,8 +122,7 @@ import GiniBankAPILibrary self.resultsDelegate?.giniCaptureAnalysisDidFinishWith(result: result) } else { - self.resultsDelegate? - .giniCaptureAnalysisDidFinishWithoutResults(analysisDelegate.tryDisplayNoResultsScreen()) + analysisDelegate.tryDisplayNoResultsScreen() self.documentService.resetToInitialState() } } diff --git a/Sources/GiniCaptureSDK/Resources/Camera/CameraBottomNavigationBar.xib b/Sources/GiniCaptureSDK/Resources/Camera/CameraBottomNavigationBar.xib index e54ad6a..3248808 100644 --- a/Sources/GiniCaptureSDK/Resources/Camera/CameraBottomNavigationBar.xib +++ b/Sources/GiniCaptureSDK/Resources/Camera/CameraBottomNavigationBar.xib @@ -1,9 +1,9 @@ - + - + @@ -14,18 +14,35 @@ - - diff --git a/Sources/GiniCaptureSDK/Resources/Camera/CameraPhone.xib b/Sources/GiniCaptureSDK/Resources/Camera/CameraPhone.xib index e12ef57..c5c829d 100644 --- a/Sources/GiniCaptureSDK/Resources/Camera/CameraPhone.xib +++ b/Sources/GiniCaptureSDK/Resources/Camera/CameraPhone.xib @@ -98,10 +98,11 @@ + - + @@ -118,7 +119,7 @@ - + diff --git a/Sources/GiniCaptureSDK/Resources/GiniImages.xcassets/onboardingGoodLightning.imageset/Contents.json b/Sources/GiniCaptureSDK/Resources/GiniImages.xcassets/onboardingGoodLighting.imageset/Contents.json similarity index 100% rename from Sources/GiniCaptureSDK/Resources/GiniImages.xcassets/onboardingGoodLightning.imageset/Contents.json rename to Sources/GiniCaptureSDK/Resources/GiniImages.xcassets/onboardingGoodLighting.imageset/Contents.json diff --git a/Sources/GiniCaptureSDK/Resources/GiniImages.xcassets/onboardingGoodLightning.imageset/Onboarding 1.pdf b/Sources/GiniCaptureSDK/Resources/GiniImages.xcassets/onboardingGoodLighting.imageset/Onboarding 1.pdf similarity index 100% rename from Sources/GiniCaptureSDK/Resources/GiniImages.xcassets/onboardingGoodLightning.imageset/Onboarding 1.pdf rename to Sources/GiniCaptureSDK/Resources/GiniImages.xcassets/onboardingGoodLighting.imageset/Onboarding 1.pdf diff --git a/Sources/GiniCaptureSDK/Resources/GiniImages.xcassets/onboardingGoodLightning.imageset/Onboarding.pdf b/Sources/GiniCaptureSDK/Resources/GiniImages.xcassets/onboardingGoodLighting.imageset/Onboarding.pdf similarity index 100% rename from Sources/GiniCaptureSDK/Resources/GiniImages.xcassets/onboardingGoodLightning.imageset/Onboarding.pdf rename to Sources/GiniCaptureSDK/Resources/GiniImages.xcassets/onboardingGoodLighting.imageset/Onboarding.pdf diff --git a/Sources/GiniCaptureSDK/Resources/OnboardingScreen/OnboardingBottomNavigationBar.xib b/Sources/GiniCaptureSDK/Resources/OnboardingScreen/OnboardingBottomNavigationBar.xib index 5a5729f..f34aef1 100644 --- a/Sources/GiniCaptureSDK/Resources/OnboardingScreen/OnboardingBottomNavigationBar.xib +++ b/Sources/GiniCaptureSDK/Resources/OnboardingScreen/OnboardingBottomNavigationBar.xib @@ -1,9 +1,9 @@ - + - + @@ -45,7 +45,7 @@ - + diff --git a/Sources/GiniCaptureSDK/Resources/OnboardingScreen/OnboardingPageCell.xib b/Sources/GiniCaptureSDK/Resources/OnboardingScreen/OnboardingPageCell.xib index d0e988b..8cbf133 100644 --- a/Sources/GiniCaptureSDK/Resources/OnboardingScreen/OnboardingPageCell.xib +++ b/Sources/GiniCaptureSDK/Resources/OnboardingScreen/OnboardingPageCell.xib @@ -20,58 +20,78 @@ - - - - - + + - - + - - + + + + + - + + + + - - - - - - - - - - - - + + + + + - @@ -80,13 +100,13 @@ - - + + - - + + - + diff --git a/Sources/GiniCaptureSDK/Resources/OnboardingScreen/OnboardingViewController.xib b/Sources/GiniCaptureSDK/Resources/OnboardingScreen/OnboardingViewController.xib index 495949d..05302de 100644 --- a/Sources/GiniCaptureSDK/Resources/OnboardingScreen/OnboardingViewController.xib +++ b/Sources/GiniCaptureSDK/Resources/OnboardingScreen/OnboardingViewController.xib @@ -36,13 +36,14 @@ - + - - - - + + + + + @@ -60,6 +61,7 @@ + diff --git a/Sources/GiniCaptureSDK/Resources/ReviewScreen/CustomReviewScreenBottomNavigationBar.xib b/Sources/GiniCaptureSDK/Resources/ReviewScreen/CustomReviewScreenBottomNavigationBar.xib deleted file mode 100644 index 9daf37f..0000000 --- a/Sources/GiniCaptureSDK/Resources/ReviewScreen/CustomReviewScreenBottomNavigationBar.xib +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Sources/GiniCaptureSDK/Resources/ReviewScreen/ReviewBottomNavigationBar.xib b/Sources/GiniCaptureSDK/Resources/ReviewScreen/ReviewBottomNavigationBar.xib index 19031f7..470e78d 100644 --- a/Sources/GiniCaptureSDK/Resources/ReviewScreen/ReviewBottomNavigationBar.xib +++ b/Sources/GiniCaptureSDK/Resources/ReviewScreen/ReviewBottomNavigationBar.xib @@ -1,9 +1,9 @@ - + - + @@ -24,7 +24,8 @@