IOS UI Customization
Getting started
IOS SDK provides various customization options with programming code.
1. Create IdenfyUISettings
Create an instance of IdenfyUISettingsV2 class:
Swift
let idenfyUISettings = IdenfyUIBuilderV2()
.build()
2. Update IdenfyUISettingsV2
let idenfySettings = IdenfyBuilderV2()
.withUISettings(idenfyUISettings)
...
.build()
Customization options
Customization with IdenfyUISettingsV2:
-
Camera OnBoarding view
IdenfyUIBuilderV2()
/**
Camera OnBoarding View acts as additional step(single or multiple), which helps user to familiarize himself with identification process
- Parameter idenfyOnBoardingViewType: sets camera onBoarding view type
*/
.withOnBoadringViewType(_ idenfyOnBoardingViewType: IdenfyOnBoardingViewTypeEnum)
...
The possible options of the Camera OnBoarding View are explained below:
IdenfyOnBoardingViewTypeEnum | Description | UI |
---|---|---|
single | Shows a single onBoarding view ONCE before verification process with all upcoming steps (This was a default setting prior to 7.x version) | |
multipleStatic | Shows an onBoarding view before EVERY step of the verification process with a static instruction list (This is a default setting starting 7.x version) |
-
Language selection
SDK shows an option to change language during the verification session:
IdenfyUIBuilderV2()
/**
Enables language selection window, which provides option to change locale
- Parameter isLanguageSelectionNeeded: changes visibility of locale selection
*/
.withLanguageSelection(_ isLanguageSelectionNeeded: Bool)
...
-
Document camera rectangle visibility
Since some documents are non regular size, therefore we have an option to hide the camera rectangle. This way the whole screen is dedicated to the document capturing.
The rectangle can be hidden for all document types:
IdenfyUIBuilderV2()
/**
* Camera rectangle will be hidden for ALL countries and document types
*/
.withDocumentCameraFrameVisibility(DocumentCameraFrameVisibility.hiddenForAllCountriesAndDocumentTypes)
...
or for specific countries and document types:
var countryDocumentMap: [String: [DocumentTypeEnum]] = [:]
countryDocumentMap["LT"] = [DocumentTypeEnum.PASSPORT]
...
let documentCameraFrameVisibility = DocumentCameraFrameVisibility.hiddenForSpecificCountriesAndDocumentTypes(countryDocumentMap: countryDocumentMap)
IdenfyUIBuilderV2()
/**
* Camera rectangle will be hidden ONLY for Lithuanian passport
*/
.withDocumentCameraFrameVisibility(documentCameraFrameVisibility)
...
-
Idenfy toolbar
SDK shows an option to hide Idenfy toolbar:
IdenfyUIBuilderV2()
/**
* An option to hide idenfy toolbar
*/
.withIdenfyToolbarHidden()
...
Customization by changing views from idenfyviews module:
All UI elements are located in the separate module - idenfyviews. Classes are marked as public, so you can override them.
1. Including idenfyviews
import idenfyviews
2. Applying customization
Take for example IdenfyConfirmationViewUISettingsV2 settings.
@objc open class IdenfyConfirmationViewUISettingsV2:NSObject {
// Idenfy Confirmation View Colors
public static var idenfyDocumentConfirmationViewBackgroundColor = IdenfyCommonColors.idenfyBackgroundColorV2
public static var idenfyDocumentConfirmationViewTitleTextColor = IdenfyCommonColors.idenfySecondColorV2
public static var idenfyDocumentConfirmationViewDescriptionTextColor = IdenfyCommonColors.idenfySecondColorV2
public static var idenfyDocumentConfirmationViewDescriptionHighlightedTextColor = IdenfyCommonColors.idenfyMainColorV2
public static var idenfyDocumentConfirmationViewBeginIdentificationButtonTextColor = IdenfyCommonColors.idenfyWhite
public static var idenfyDocumentConfirmationViewDocumentStepTitleTextColor = IdenfyCommonColors.idenfySecondColorV2
public static var idenfyDocumentConfirmationViewDocumentStepTitleHighlightedTextColor = IdenfyCommonColors.idenfyMainColorV2
public static var idenfyDocumentConfirmationViewUploadDocumentPhotoTitleTextColor = IdenfyCommonColors.idenfySecondColorV2
public static var idenfyDocumentConfirmationViewDocumentStepCellNumberTextColor = IdenfyCommonColors.idenfyWhite
public static var idenfyDocumentConfirmationViewDocumentStepCellTitleTextColor = IdenfyCommonColors.idenfySecondColorV2
public static var idenfyDocumentConfirmationViewContentMaskForegroundColor = IdenfyCommonColors.idenfyBackgroundColorV2.withAlphaComponent(0.9)
public static var idenfyDocumentConfirmationViewUploadIconTintColor:UIColor? = IdenfyCommonColors.idenfyMainColorV2
public static var idenfyDocumentConfirmationViewDocumentStepCircleTintColor:UIColor? = IdenfyCommonColors.idenfyMainColorV2
// Idenfy Confirmation View Fonts
public static var idenfyDocumentConfirmationViewTitleFont = UIFont(name: ConstsIdenfyFonts.idenfyFontBoldV2, size: 22)
public static var idenfyDocumentConfirmationViewDescriptionFont = UIFont(name: ConstsIdenfyFonts.idenfyFontRegularV2, size: 13)
public static var idenfyDocumentConfirmationViewDescriptionHighlightedFont = UIFont(name: ConstsIdenfyFonts.idenfyFontBoldV2, size: 13)
public static var idenfyDocumentConfirmationViewDocumentStepTitleFont = UIFont(name: ConstsIdenfyFonts.idenfyFontBoldV2, size: 13)
public static var idenfyDocumentConfirmationViewUploadTitleFont = UIFont(name: ConstsIdenfyFonts.idenfyFontRegularV2, size: 13)
public static var idenfyDocumentConfirmationViewDocumentStepNumberFont = UIFont(name: ConstsIdenfyFonts.idenfyFontBoldV2, size: 11)
public static var idenfyDocumentConfirmationViewDocumentStepFont = UIFont(name: ConstsIdenfyFonts.idenfyFontRegularV2, size: 13)
// Idenfy Confirmation View Style
public static var idenfyDocumentConfirmationViewDocumentStepCellHeight = CGFloat(30)
}
You can customize it in the following manner:
Example:
IdenfyConfirmationViewUISettingsV2.idenfyDocumentConfirmationViewBackgroundColor = UIColor.red
IdenfyConfirmationViewUISettingsV2.idenfyDocumentConfirmationViewTitleTextColor = UIColor.red
UI Settings classes of all the views can be found in our repository
3. Applying SDK wide color changes
If color and assets changes are the only requirement, then it can be easily customized by changing main colors.
Information about colors:
Color name | Description | Default color value |
---|---|---|
idenfyMainColorV2 | Defines the color of most single colored assets and focused parts in SDK. | #536DFE |
idenfyMainDarkerColorV2 | Defines the color of some focused parts in SDK, similar to idenfyMainColorV2. | #5D7CE4 |
idenfyBackgroundColorV2 | Defines the background color. | #FBFBFB |
idenfySecondColorV2 | Defines the text color. | #F2353B4E |
You can customize it in the following manner:
Example:
IdenfyCommonColors.idenfyMainColorV2 = UIColor.green
IdenfyCommonColors.idenfyMainDarkerColorV2 = UIColor.green
Colors also are applied on images, which use a single color from IdenfyImagesV2.xcassets. If perhaps you decided to override our provided images with more sophisticated icons, which use more than 1 color, then you can easily disable tint on images. You need set color values as nil.
Example:
IdenfyConfirmationViewUISettingsV2.idenfyDocumentConfirmationViewDocumentStepCircleTintColor = nil
IdenfyConfirmationViewUISettingsV2.idenfyDocumentConfirmationViewUploadIconTintColor = nil
IdenfyToolbarUISettingsV2.idenfyDefaultToolbarLogoIconTintColor = nil
IdenfyToolbarUISettingsV2.idenfyDefaultToolbarBackIconTintColor = nil
IdenfyToolbarUISettingsV2.idenfyLanguageSelectionToolbarLanguageSelectionIconTintColor = UIColor.yellow
IdenfyToolbarUISettingsV2.idenfyLanguageSelectionToolbarCloseIconTintColor = nil
IdenfyToolbarUISettingsV2.idenfyCameraPreviewSessionToolbarBackIconTintColor = nil
IdenfyIdentificationResultsViewUISettingsV2.idenfyIdentificationResultsDividerIconStatusErrorTintColor = nil
IdenfyIdentificationResultsViewUISettingsV2.idenfyIdentificationResultsDividerIconStatusLoadingTintColor = nil
Customization by providing supplying your own implementations of UIViews protocol:
For more advanced customization (fonts, constraints, the layout structure, etc.) it is better to override our layouts, by providing your own implementations.
All layouts used in iDenfySDK are located in the idenfyviews module and expose public protocols.
1. Create an instance of IdenfyViewsV2
Use IdenfyViewsBuilderV2 to create an instance of IdenfyViewsV2 with your custom views, which conform to protocols provided by the iDenfySDK. Take a look at the methods of the IdenfyViewsBuilderV2 class.
let idenfyViewsV2:IdenfyViewsV2 = IdenfyViewsBuilderV2()
.withSplashScreenV2View(SplashScreenV2View())
...
.build()
2. Initiliaze iDenfySDK with an instance of IdenfyViewsV2
Pass created instance of the IdenfyViewsV2 class to the initializeIdenfySDKV2WithManual() method.
idenfyController.initializeIdenfySDKV2WithManual(idenfySettingsV2: idenfySettingsV2, idenfyViewsV2: idenfyViewsV2)
Example of the customization flow
1. Download the sample app and follow the instructions:
Download the sample app here and follow config instructions.
Then set sdkInitFlow to SDKInitFlow.CustomWithImplementedViews.
2. Change the required view.
Select a view you want to modify. As an example we will modify the button in the ConfirmationViewV2. Go to the /custom/viewsofviewcontrollers/ConfirmationViewV2 Then add following modifications:
setupBeginIdentificationButton method constraint change
private func setupBeginIdentificationButton() {
addSubview(beginIdentificationButton)
beginIdentificationButton.rightAnchor.constraint(equalTo: safeRightAnchor, constant: -32).isActive = true
beginIdentificationButton.leftAnchor.constraint(equalTo: safeLeftAnchor, constant: 32).isActive = true
beginIdentificationButton.bottomAnchor.constraint(equalTo: safeBottomAnchor, constant: -48).isActive = true
beginIdentificationButton.heightAnchor.constraint(equalToConstant: 42).isActive = true
}
Button change
public var beginIdentificationButton: UIButton = {
let button = UIButton(frame: .zero)
button.translatesAutoresizingMaskIntoConstraints = false
button.contentMode = .scaleToFill
button.isUserInteractionEnabled = true
button.titleLabel?.textColor = UIColor.black
button.setTitleColor(UIColor.black, for: .normal)
button.titleLabel?.textAlignment = .center
button.layer.cornerRadius = 12
button.layer.borderWidth = 3
button.layer.borderColor = UIColor.black.cgColor
button.layer.masksToBounds = true
button.titleLabel?.font = IdenfyButtonsUISettingsV2.idenfyButtonFont
return button
}()
Global colors change, to remove the gradient
override public init(frame: CGRect) {
super.init(frame: frame)
// Applying global gradient changes
IdenfyButtonsUISettingsV2.idenfyGradientButtonColorStart = UIColor.white
IdenfyButtonsUISettingsV2.idenfyGradientButtonColorEnd = UIColor.white
setupConstraints()
}
3. Ensure final changes, see the result
The final code looks like this:
import Foundation
import iDenfySDK
import idenfyviews
import UIKit
@objc open class ConfirmationViewV2: UIView, ConfirmationViewableV2 {
open weak var delegate: ConfirmationViewButtonActionsDelegate?
override public init(frame: CGRect) {
super.init(frame: frame)
// Applying global gradient changes
IdenfyButtonsUISettingsV2.idenfyGradientButtonColorStart = UIColor.white
IdenfyButtonsUISettingsV2.idenfyGradientButtonColorEnd = UIColor.white
setupConstraints()
}
public required init?(coder _: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
public var toolbar: IdenfyToolbarV2Default = {
let toolbar = IdenfyToolbarV2Default(frame: .zero)
toolbar.translatesAutoresizingMaskIntoConstraints = false
return toolbar
}()
public var confirmationTitle: UILabel = {
let label = UILabel(frame: .zero)
label.translatesAutoresizingMaskIntoConstraints = false
label.numberOfLines = 0
label.font = IdenfyConfirmationViewUISettingsV2.idenfyDocumentConfirmationViewTitleFont
label.textAlignment = .center
label.textColor = IdenfyConfirmationViewUISettingsV2.idenfyDocumentConfirmationViewTitleTextColor
return label
}()
public var confirmationDescription: UILabel = {
let label = UILabel(frame: .zero)
label.numberOfLines = 0
label.translatesAutoresizingMaskIntoConstraints = false
label.font = IdenfyConfirmationViewUISettingsV2.idenfyDocumentConfirmationViewDescriptionFont
label.textAlignment = .center
label.textColor = IdenfyConfirmationViewUISettingsV2.idenfyDocumentConfirmationViewDescriptionTextColor
return label
}()
public var documentTypeCircle: UIImageView = {
let imageView = UIImageView()
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.isOpaque = true
imageView.image = IdenfyViewUtils.getImage(ConstsIdenfyImages.idenfy_ic_confirmation_document_circle)
imageView.contentMode = .scaleAspectFit
return imageView
}()
public var documentTypeImageView: UIImageView = {
let imageView = UIImageView()
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.isOpaque = true
imageView.image = IdenfyViewUtils.getImage(ConstsIdenfyImages.idenfy_ic_documents_type_selection_id_card_v2)
imageView.contentMode = .scaleAspectFit
return imageView
}()
public var documentStepTitle: UILabel = {
let label = UILabel(frame: .zero)
label.numberOfLines = 0
label.translatesAutoresizingMaskIntoConstraints = false
label.font = IdenfyConfirmationViewUISettingsV2.idenfyDocumentConfirmationViewDocumentStepTitleFont
label.textAlignment = .center
label.textColor = IdenfyConfirmationViewUISettingsV2.idenfyDocumentConfirmationViewDocumentStepTitleTextColor
return label
}()
public var documentStepTableView: UITableView = {
let tableView = UITableView()
tableView.translatesAutoresizingMaskIntoConstraints = false
tableView.bounces = false
tableView.isScrollEnabled = false
tableView.allowsSelection = false
tableView.allowsMultipleSelection = false
tableView.allowsSelectionDuringEditing = false
tableView.allowsMultipleSelectionDuringEditing = false
tableView.backgroundColor = .clear
return tableView
}()
public var uploadImageView: UIImageView = {
let imageView = UIImageView()
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.isOpaque = true
imageView.image = IdenfyViewUtils.getImage(ConstsIdenfyImages.idenfy_ic_confirmation_upload_photo)
imageView.setImageColor(IdenfyConfirmationViewUISettingsV2.idenfyDocumentConfirmationViewUploadIconTintColor)
imageView.contentMode = .scaleAspectFit
return imageView
}()
public var uploadTitle: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.font = IdenfyConfirmationViewUISettingsV2.idenfyDocumentConfirmationViewUploadTitleFont
label.textAlignment = .center
label.numberOfLines = 0
label.textColor = IdenfyConfirmationViewUISettingsV2.idenfyDocumentConfirmationViewUploadDocumentPhotoTitleTextColor
return label
}()
public var beginIdentificationButton: UIButton = {
let button = UIButton(frame: .zero)
button.translatesAutoresizingMaskIntoConstraints = false
button.contentMode = .scaleToFill
button.isUserInteractionEnabled = true
button.titleLabel?.textColor = UIColor.black
button.setTitleColor(UIColor.black, for: .normal)
button.titleLabel?.textAlignment = .center
button.layer.cornerRadius = 12
button.layer.borderWidth = 3
button.layer.borderColor = UIColor.black.cgColor
button.layer.masksToBounds = true
button.titleLabel?.font = IdenfyButtonsUISettingsV2.idenfyButtonFont
return button
}()
public var middleContentScrollView: UIScrollView = {
let scroll = UIScrollView()
scroll.translatesAutoresizingMaskIntoConstraints = false
scroll.isUserInteractionEnabled = true
scroll.bounces = false
return scroll
}()
public var scrollMask: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
view.isUserInteractionEnabled = false
view.isHidden = true
return view
}()
open func setupConstraints() {
backgroundColor = IdenfyConfirmationViewUISettingsV2.idenfyDocumentConfirmationViewBackgroundColor
setupToolbar()
setupTopTitle()
setupBeginIdentificationButton()
setupMiddleContentScrollView()
setupMiddleContentView()
setupButtonActions()
}
private func setupButtonActions() {
beginIdentificationButton.addTarget(self, action: #selector(beginIdentificationButtonPressed), for: .touchUpInside)
}
@objc func beginIdentificationButtonPressed() {
delegate?.beginIdentificationButtonPressed()
}
private func setupToolbar() {
addSubview(toolbar)
toolbar.leftAnchor.constraint(equalTo: safeLeftAnchor).isActive = true
toolbar.rightAnchor.constraint(equalTo: safeRightAnchor).isActive = true
if #available(iOS 11.0, *) {
toolbar.topAnchor.constraint(equalTo: self.safeTopAnchor).isActive = true
} else {
toolbar.topAnchor.constraint(equalTo: safeTopAnchor, constant: 20).isActive = true
}
toolbar.heightAnchor.constraint(equalToConstant: 60).isActive = true
}
private func setupTopTitle() {
addSubview(confirmationTitle)
confirmationTitle.rightAnchor.constraint(equalTo: safeRightAnchor, constant: -16).isActive = true
confirmationTitle.leftAnchor.constraint(equalTo: safeLeftAnchor, constant: 16).isActive = true
confirmationTitle.topAnchor.constraint(equalTo: toolbar.bottomAnchor, constant: 24).isActive = true
addSubview(confirmationDescription)
confirmationDescription.widthAnchor.constraint(equalTo: confirmationTitle.widthAnchor, multiplier: 0.8).isActive = true
confirmationDescription.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
confirmationDescription.topAnchor.constraint(equalTo: confirmationTitle.bottomAnchor, constant: 16).isActive = true
}
private func setupBeginIdentificationButton() {
addSubview(beginIdentificationButton)
beginIdentificationButton.rightAnchor.constraint(equalTo: safeRightAnchor, constant: -32).isActive = true
beginIdentificationButton.leftAnchor.constraint(equalTo: safeLeftAnchor, constant: 32).isActive = true
beginIdentificationButton.bottomAnchor.constraint(equalTo: safeBottomAnchor, constant: -48).isActive = true
beginIdentificationButton.heightAnchor.constraint(equalToConstant: 42).isActive = true
}
private func setupMiddleContentScrollView() {
addSubview(middleContentScrollView)
middleContentScrollView.topAnchor.constraint(equalTo: confirmationDescription.bottomAnchor, constant: 16).isActive = true
middleContentScrollView.leftAnchor.constraint(equalTo: safeLeftAnchor).isActive = true
middleContentScrollView.rightAnchor.constraint(equalTo: safeRightAnchor).isActive = true
middleContentScrollView.bottomAnchor.constraint(equalTo: beginIdentificationButton.topAnchor, constant: -8).isActive = true
addSubview(scrollMask)
scrollMask.centerXAnchor.constraint(equalTo: middleContentScrollView.centerXAnchor).isActive = true
scrollMask.centerYAnchor.constraint(equalTo: middleContentScrollView.centerYAnchor).isActive = true
scrollMask.widthAnchor.constraint(equalTo: middleContentScrollView.widthAnchor).isActive = true
scrollMask.heightAnchor.constraint(equalTo: middleContentScrollView.heightAnchor).isActive = true
}
private func setupMiddleContentView() {
middleContentScrollView.addSubview(documentTypeCircle)
documentTypeCircle.topAnchor.constraint(equalTo: middleContentScrollView.topAnchor, constant: 8).isActive = true
documentTypeCircle.centerXAnchor.constraint(equalTo: middleContentScrollView.centerXAnchor).isActive = true
documentTypeCircle.widthAnchor.constraint(equalTo: middleContentScrollView.widthAnchor, multiplier: 0.3).isActive = true
documentTypeCircle.heightAnchor.constraint(equalTo: documentTypeCircle.widthAnchor, multiplier: 1).isActive = true
middleContentScrollView.addSubview(documentTypeImageView)
documentTypeImageView.heightAnchor.constraint(equalTo: documentTypeCircle.heightAnchor, multiplier: 0.7).isActive = true
documentTypeImageView.centerYAnchor.constraint(equalTo: documentTypeCircle.centerYAnchor).isActive = true
documentTypeImageView.widthAnchor.constraint(equalTo: documentTypeCircle.widthAnchor, multiplier: 0.7).isActive = true
documentTypeImageView.centerXAnchor.constraint(equalTo: documentTypeCircle.centerXAnchor).isActive = true
middleContentScrollView.addSubview(documentStepTitle)
documentStepTitle.centerXAnchor.constraint(equalTo: middleContentScrollView.centerXAnchor).isActive = true
documentStepTitle.topAnchor.constraint(equalTo: documentTypeCircle.bottomAnchor, constant: 24).isActive = true
middleContentScrollView.addSubview(documentStepTableView)
documentStepTableView.topAnchor.constraint(equalTo: documentStepTitle.bottomAnchor, constant: 16).isActive = true
if UIDevice.current.userInterfaceIdiom == .pad {
NSLayoutConstraint(item: documentStepTableView, attribute: .centerX, relatedBy: .equal, toItem: self, attribute: .centerX, multiplier: 1, constant: 0).isActive = true
} else {
NSLayoutConstraint(item: documentStepTableView, attribute: .centerX, relatedBy: .equal, toItem: self, attribute: .centerX, multiplier: 1.2, constant: 0).isActive = true
}
documentStepTableView.widthAnchor.constraint(equalTo: documentStepTitle.widthAnchor, multiplier: 1.5).isActive = true
middleContentScrollView.addSubview(uploadImageView)
uploadImageView.centerXAnchor.constraint(equalTo: middleContentScrollView.centerXAnchor).isActive = true
uploadImageView.topAnchor.constraint(equalTo: documentStepTableView.bottomAnchor, constant: 24).isActive = true
uploadImageView.widthAnchor.constraint(equalToConstant: 25).isActive = true
uploadImageView.heightAnchor.constraint(equalTo: uploadImageView.widthAnchor, multiplier: 1).isActive = true
middleContentScrollView.addSubview(uploadTitle)
uploadTitle.leftAnchor.constraint(equalTo: middleContentScrollView.safeLeftAnchor, constant: 32).isActive = true
uploadTitle.rightAnchor.constraint(equalTo: middleContentScrollView.safeRightAnchor, constant: -32).isActive = true
uploadTitle.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
uploadTitle.topAnchor.constraint(equalTo: uploadImageView.bottomAnchor, constant: 16).isActive = true
}
}
@objc open class DocumentStepCell: UITableViewCell, DocumentStepCellViewable {
public let cellView: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
public var documentStepNumber: UILabel = {
let label = UILabel(frame: .zero)
label.numberOfLines = 0
label.translatesAutoresizingMaskIntoConstraints = false
label.font = IdenfyConfirmationViewUISettingsV2.idenfyDocumentConfirmationViewDocumentStepNumberFont
label.text = "1"
label.textColor = IdenfyConfirmationViewUISettingsV2.idenfyDocumentConfirmationViewDocumentStepCellNumberTextColor
return label
}()
public var documentStepLabel: UILabel = {
let label = UILabel(frame: .zero)
label.numberOfLines = 0
label.translatesAutoresizingMaskIntoConstraints = false
label.font = IdenfyConfirmationViewUISettingsV2.idenfyDocumentConfirmationViewDocumentStepFont
label.text = "Step"
label.textAlignment = .left
label.textColor = IdenfyConfirmationViewUISettingsV2.idenfyDocumentConfirmationViewDocumentStepCellTitleTextColor
return label
}()
public var documentStepCircle: UIImageView = {
let imageView = UIImageView()
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.contentMode = .scaleAspectFit
imageView.isOpaque = true
imageView.image = IdenfyViewUtils.getImage(ConstsIdenfyImages.idenfy_ic_confirmation_item_step_circle)
imageView.setImageColor(IdenfyConfirmationViewUISettingsV2.idenfyDocumentConfirmationViewDocumentStepCircleTintColor)
return imageView
}()
override public init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setupView()
}
public required init?(coder _: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
open func setupView() {
addSubview(cellView)
cellView.leftAnchor.constraint(equalTo: safeLeftAnchor).isActive = true
cellView.rightAnchor.constraint(equalTo: safeRightAnchor).isActive = true
cellView.topAnchor.constraint(equalTo: safeTopAnchor).isActive = true
cellView.bottomAnchor.constraint(equalTo: safeBottomAnchor).isActive = true
cellView.addSubview(documentStepCircle)
documentStepCircle.topAnchor.constraint(equalTo: cellView.safeTopAnchor).isActive = true
documentStepCircle.bottomAnchor.constraint(equalTo: cellView.safeBottomAnchor).isActive = true
documentStepCircle.centerYAnchor.constraint(equalTo: cellView.centerYAnchor).isActive = true
documentStepCircle.leftAnchor.constraint(equalTo: cellView.safeLeftAnchor).isActive = true
cellView.addSubview(documentStepLabel)
documentStepLabel.centerYAnchor.constraint(equalTo: cellView.centerYAnchor).isActive = true
documentStepLabel.leftAnchor.constraint(equalTo: documentStepCircle.rightAnchor, constant: 8).isActive = true
documentStepLabel.widthAnchor.constraint(equalToConstant: frame.width * 0.65).isActive = true
cellView.addSubview(documentStepNumber)
documentStepNumber.centerXAnchor.constraint(equalTo: documentStepCircle.centerXAnchor).isActive = true
documentStepNumber.centerYAnchor.constraint(equalTo: documentStepCircle.centerYAnchor).isActive = true
}
}
The result is here:
4. Important things & suggestions
If you need very custom issuing country or document country selection screens or even merge them into a single screen, it is always better to use the skipping views customization options. That way it will be easier to maintain the customization code.
If you need a very custom verification results screen it is better to use the CustomWaitingViewController solution.
Customization by providing a CustomWaitingViewController:
To fully customize your verification results waiting view, we provide a solution to pass your own view controller.
After supplying your own implementation of the results ViewController, the SDK will not load its own ViewController and navigate directly to your own VC.
Then you can control when and after which additional steps do you want to retry the verification session. The example below illustrates the flow:
1. Create a class, that implements IdenfyInProcessIdentificationResultsDelegate
Pass an instance of your created class to the initializeWithCustomWaitingViewController() method of IdenfyController.
idenfyController.initializeWithCustomWaitingViewController(idenfySettingsV2: idenfySettingsV2, idenfyInProcessIdentificationResultsDelegate: idenfyInProcessIdentificationResultsDelegateImpl())
2. Create an instance of your CustomWaitingViewController
Return created instance in the onIdenfyFlowFinished() method of your IdenfyInProcessIdentificationResultsDelegate implementation.
/**
- Parameter idenfyIdentificationResultStatus: returns a current verification status. This status is updated until FINISHED is returned.
*/
func onIdenfyFlowFinished(idenfyFlowSettings _: IdenfyFlowSettings) -> CustomWaitingViewController {
return CustomWaitingViewController.ViewControllerProvided(vc: PartnersCustomWaitingViewController())
}
For details regarding the verification process, you can look at IdenfyFlowSettings.
/**
Has set of properties for providing information about user verification flow.
*/
public struct IdenfyFlowSettings {
/**
Provides an array of steps used during the verification process.
*/
public let identificationSteps: [Step]
}
3. Having received verification results, call a static method of IdenfyController to continue the flow
Your created IdenfyInProcessIdentificationResultsDelegate implementation has onIdentificationStatusReceived() method, which returns an IdenfyIdentificationResultStatus. When IdenfyIdentificationStatus is FINISHED, call a static continueFlow() method of IdenfyController.
/**
- Parameter idenfyIdentificationResultStatus: returns a current verification status. This status is updated until FINISHED is returned.
*/
func onIdentificationStatusReceived(idenfyIdentificationResultStatus: IdenfyIdentificationResultStatus) {
switch idenfyIdentificationResultStatus.idenfyProcessingResultState {
case .FINISHED(canRetry: _, retakeSteps: _):
IdenfyController.continueFlow()
break
case .PROCESSING:
break
}
}
IdenfyIdentificationResultStatus class contains all information about the current state of verification results, using this you can fully customize your views.
public class IdenfyIdentificationResultStatus {
public let idenfyIdentificationStatus: IdenfyIdentificationStatus
public let idenfyProcessingResultState: IdenfyProcessingResultState
public init(idenfyIdentificationStatus: IdenfyIdentificationStatus, idenfyProcessingResultState: IdenfyProcessingResultState) {
self.idenfyIdentificationStatus = idenfyIdentificationStatus
self.idenfyProcessingResultState = idenfyProcessingResultState
}
}
public enum IdenfyProcessingResultState {
case PROCESSING
case FINISHED(canRetry: Bool, retakeSteps: RetakeSteps?)
}
public enum IdenfyIdentificationStatus: String, Codable {
case APPROVED
case DENIED
case SUSPECTED
case REVIEWING
case UNKNOWN
}
Customization with IdenfyUISettingsV2:
Adding instructions in camera session.
The iDenfySDK provides informative instructions during the verification session. They can provide valuable information for the user and help to tackle common issues: bad lightning, wrong document side, etc. Instructions can be customized, by changing all UI elements or even using your MP4 video files. Instructions are configured by your backend settings and can be overridden with the SDK settings.
Using IdenfyInstructionsEnum dialog
Using IdenfyInstructionsEnum none
1. Enable instructions in IdenfyUISettingsV2
let idenfyUISettingsV2 = IdenfyUIBuilderV2()
.withInstructions(IdenfyInstructionsEnum.dialog)
.build()
Liveness Customization
iDenfy SDK provides additional liveness customization.
1. Creating IdenfyLivenessUIHelper
let idenfyLivenessUISettings = IdenfyLivenessUISettings()
2.1 Applying regular settings
If you only need color, text, or width customization, you can use properties from the IdenfyLivenessUISettings class.
@objc public class IdenfyLivenessUISettings: NSObject {
// Used for different ui parts
public var idenfyLivenessPrimaryColor = UIColor.white
public var idenfyLivenessAccentColor = UIColor(red: 139 / 255.0, green: 199 / 255.0, blue: 224 / 255.0, alpha: 1.0)
public var idenfyLivenessTextColor = UIColor.black
// Liveness session feedback settings
public var livenessFeedbackBackgroundColor = UIColor(red: 139 / 255.0, green: 199 / 255.0, blue: 224 / 255.0, alpha: 1.0)
public var livenessFeedbackFont: UIFont = UIFont(name: ConstsIdenfyFonts.idenfyFontBoldV2, size: 18) ?? UIFont.boldSystemFont(ofSize: 18)
public var livenessFeedbackFontSizeMobile: CGFloat?
public var livenessFeedbackFontSizeTablet: CGFloat?
public var livenessFeedbackFontColor: UIColor?
// Liveness session frame settings
public var livenessFrameBackgroundColor: UIColor = UIColor.black.withAlphaComponent(0.72)
public var livenessFrameColor: UIColor?
public var livenessFrameWidth: Int32? = 0
//Liveness session cancel button settings
public var livenessCancelButtonImage = UIImage(named: "idenfy_ic_liveliness_camera_session_cancel_image", in: Bundle(identifier: "com.idenfy.idenfysdk"), compatibleWith: nil)
// Liveness session progress settings
public var livenessIdentificationOvalProgressColor1 = UIColor(red: 139 / 255.0, green: 199 / 255.0, blue: 224 / 255.0, alpha: 1.0)
public var livenessIdentificationProgressStrokeColor = UIColor(red: 139 / 255.0, green: 199 / 255.0, blue: 224 / 255.0, alpha: 1.0)
public var livenessIdentificationOvalProgressColor2 = UIColor(red: 139 / 255.0, green: 199 / 255.0, blue: 224 / 255.0, alpha: 1.0)
public var livenessIdentificationProgressStrokeWidth: Int32 = 4
public var livenessIdentificationStrokeWidth: Int32 = 3
public var livenessIdentificationProgressRadialOffset: Int32 = 6
// Liveness session overlay settings
public var livenessOverlayBrandingImage = UIImage(named: "idenfy_ic_liveliness_overlay_branding_image", in: Bundle(identifier: "com.idenfy.idenfysdk"), compatibleWith: nil)
// Liveness ready screen settings
public var livenessReadyScreenForegroundColor: UIColor?
public var livenessReadyScreenBackgroundColors: [UIColor]?
public var livenessReadyScreenTextBackgroundColor: UIColor?
public var livenessReadyScreenButtonBorderColor: UIColor?
public var livenessReadyScreenButtonBorderWidth: Int32? = 1
public var livenessReadyScreenButtonCornerRadius: Int32? = 4
public var livenessReadyScreenButtonBackgroundNormalColor: UIColor?
public var livenessReadyScreenButtonBackgroundHighlightedColor: UIColor?
public var livenessReadyScreenShowBrandingImage: Bool? = true
//Camera permissions screen
public var livenessCameraPermissionsScreenImage = UIImage(named: "idenfy_ic_liveliness_camera_permissions_screen_image", in: Bundle(identifier: "com.idenfy.idenfysdk"), compatibleWith: nil)
// Liveness result screen settings
public var livenessResultScreenForegroundColor: UIColor?
public var livenessResultScreenIndicatorColor: UIColor?
public var livenessResultScreenUploadProgressFillColor: UIColor?
public var livenessResultScreenUploadProgressTrackColor: UIColor?
public var livenessResultScreenShowUploadProgressBar: Bool? = true
public var livenessResultScreenResultAnimationSuccessBackgroundImage = UIImage(named: "idenfy_ic_liveliness_results_success_icon_background", in: Bundle(identifier: "com.idenfy.idenfysdk"), compatibleWith: nil)
public var livenessCustomUISettings: FaceTecCustomization?
// ID check customization
public var livenessIdCheckCustomization = LivenessIdCheckCustomization()
}
@objc public class LivenessIdCheckCustomization: NSObject {
public var buttonBackgroundNormalColor: UIColor?
public var buttonBackgroundHighlightColor: UIColor?
public var captureScreenTextBackgroundColor: UIColor?
public var reviewScreenTextBackgroundColor: UIColor?
public var captureFrameStrokeColor: UIColor?
}
2.2 Applying full customization
If you require more changes, you can directly set livenessCustomUISettings property in the IdenfyLivenessUISettings with your instance of the FaceTecCustomization class:
idenfyLivenessUISettings.livenessCustomUISettings = FaceTecCustomization()
Full customization options are available here.
It will override all other set properties of the IdenfyLivenessUISettings class.
3. Updating IdenfyUISettings
- V1
- V2
let idenfyUISettings = IdenfyUIBuilder()
.withLivenessUISettings(idenfyLivenessUISettings)
...
.build()
let idenfyUISettingsV2 = IdenfyUIBuilderV2()
.withLivenessUISettings(idenfyLivenessUISettings)
...
.build()