diff --git a/AcuantCamera/AcuantCamera/Camera/Document/DocumentCameraController.swift b/AcuantCamera/AcuantCamera/Camera/Document/DocumentCameraController.swift index 7f67015..4074eaa 100644 --- a/AcuantCamera/AcuantCamera/Camera/Document/DocumentCameraController.swift +++ b/AcuantCamera/AcuantCamera/Camera/Document/DocumentCameraController.swift @@ -46,6 +46,8 @@ import AcuantCommon private var currentStateCount = 0 private var isNavigationHidden = false + + public var currentLangCode: String? public class func getCameraController(delegate: CameraCaptureDelegate, cameraOptions: CameraOptions) -> DocumentCameraController { let c = DocumentCameraController() @@ -69,6 +71,10 @@ import AcuantCommon let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(touchAction(_:))) self.view.addGestureRecognizer(gestureRecognizer) + + if let currentLanguageCode = currentLangCode { + DocLanguageManager.shared.langCode = currentLanguageCode + } } @objc internal func touchAction(_ sender: UITapGestureRecognizer) { @@ -134,7 +140,7 @@ import AcuantCommon queue: .main) { [weak self] _ in guard let self = self, self.alertView == nil else { return } - self.messageLayer.string = NSLocalizedString("acuant_camera_paused", comment: "") + self.messageLayer.string = "acuant_camera_paused".localizedDocString let alertView = CameraAlertView(frame: self.view.bounds) self.view.addSubview(alertView) self.view.bringSubviewToFront(alertView) @@ -149,7 +155,7 @@ import AcuantCommon self.alertView?.removeFromSuperview() self.alertView = nil if !self.autoCapture { - self.messageLayer.string = NSLocalizedString("acuant_camera_manual_capture", comment: "") + self.messageLayer.string = "acuant_camera_manual_capture".localizedDocString } } } @@ -347,7 +353,7 @@ import AcuantCommon } if let localString = localString { - self.cancelCapture(state: state, message: NSLocalizedString(localString, comment: "")) + self.cancelCapture(state: state, message: localString.localizedDocString) } else { self.setLookFromState(state: state) } @@ -403,7 +409,7 @@ import AcuantCommon attribs[NSAttributedString.Key.foregroundColor]=UIColor.white attribs[NSAttributedString.Key.baselineOffset]=4 - let str = NSMutableAttributedString.init(string: "BACK", attributes: attribs as [NSAttributedString.Key : Any]) + let str = NSMutableAttributedString.init(string: "acuant_back_button".localizedDocString, attributes: attribs as [NSAttributedString.Key : Any]) backButton.setAttributedTitle(str, for: .normal) backButton.addTarget(self, action: #selector(backTapped(_:)), for: .touchUpInside) backButton.isOpaque=true @@ -425,7 +431,7 @@ extension DocumentCameraController: DocumentCaptureDelegate { public func readyToCapture() { DispatchQueue.main.async { if self.messageLayer != nil { - self.messageLayer.string = NSLocalizedString("acuant_camera_capturing", comment: "") + self.messageLayer.string = "acuant_camera_capturing".localizedDocString if self.autoCapture { self.setLookFromState(state: DocumentCameraController.CameraState.Capture) } else { @@ -476,7 +482,7 @@ extension DocumentCameraController: FrameAnalysisDelegate { self.transitionState(state: CameraState.Hold) if self.isDocumentMoved(points: scaledPoints) { - self.cancelCapture(state: CameraState.Steady, message: NSLocalizedString("acuant_camera_hold_steady", comment: "")) + self.cancelCapture(state: CameraState.Steady, message: "acuant_camera_hold_steady".localizedDocString) } else if !self.captured { self.triggerCapture() } @@ -499,9 +505,52 @@ extension DocumentCameraController: AutoCaptureDelegate { self.autoCapture = autoCapture if !autoCapture { DispatchQueue.main.async { - self.messageLayer.string = NSLocalizedString("acuant_camera_manual_capture", comment: "") + self.messageLayer.string = "acuant_camera_manual_capture".localizedDocString + } + } + } + +} + +// MARK: - Custom Localization + + open class DocLanguageManager { + static let shared = DocLanguageManager() + + var langCode: String? { + didSet { + if let appLanguage = langCode { + currentLanguage = appLanguage + } else { + currentLanguage = Locale.current.languageCode ?? "en" + } + } + } + + private(set) var currentLanguage: String + + private init() { + if let appLanguage = langCode { + currentLanguage = appLanguage + } else { + currentLanguage = Locale.current.languageCode ?? "en" } } + + public static func localizedString(_ key: String, comment: String = "") -> String { + let bundle = Bundle.main + guard let path = bundle.path(forResource: DocLanguageManager.shared.currentLanguage, ofType: "lproj"), + let string = Bundle(path: path)?.localizedString(forKey: key, value: "", table: "") else { + return NSLocalizedString(key, comment: comment) + } + return string } } + +extension String { + public var localizedDocString: String { + return DocLanguageManager.localizedString(self) + } +} + diff --git a/AcuantCamera/AcuantCamera/View/CameraTextView.swift b/AcuantCamera/AcuantCamera/View/CameraTextView.swift index 159d48a..396a33a 100644 --- a/AcuantCamera/AcuantCamera/View/CameraTextView.swift +++ b/AcuantCamera/AcuantCamera/View/CameraTextView.swift @@ -31,9 +31,9 @@ public class CameraTextView: CATextLayer { super.init() self.opacity = 0.7 if autoCapture { - self.string = NSLocalizedString("acuant_camera_align", comment: "") + self.string = "acuant_camera_align".localizedDocString } else { - self.string = NSLocalizedString("acuant_camera_manual_capture", comment: "") + self.string = "acuant_camera_manual_capture".localizedDocString } self.alignmentMode = CATextLayerAlignmentMode.center self.cornerRadius = 10 @@ -59,11 +59,18 @@ public class CameraTextView: CATextLayer { } private func fitTextToFrame() { + // Calculates the string size. var stringSize: CGSize { get { return (string as? String)!.size(ofFont: UIFont(name: (font as! UIFont).fontName, size: fontSize)!) } } + + // Frame is rotating while font dimensions are stationary + let frameWidth = max(frame.width, frame.height) + let frameHeight = min(frame.width, frame.height) + + // Decreases the font size until criteria met let margin: CGFloat = 2 - while max(frame.width, frame.height) <= max(stringSize.width, stringSize.height) + margin { + while (frameWidth <= stringSize.width + margin) || frameHeight <= stringSize.height + margin { fontSize -= 1 } } diff --git a/AcuantFaceCapture/AcuantFaceCapture/FaceCaptureController.swift b/AcuantFaceCapture/AcuantFaceCapture/FaceCaptureController.swift index 2d93632..68af72c 100644 --- a/AcuantFaceCapture/AcuantFaceCapture/FaceCaptureController.swift +++ b/AcuantFaceCapture/AcuantFaceCapture/FaceCaptureController.swift @@ -32,9 +32,15 @@ public class FaceCaptureController: UIViewController { private var isNavigationHidden = false private let frameThrottleDuration = 0.2 private var isCaptured = false + + public var currentLangCode: String? override public func viewDidLoad() { super.viewDidLoad() + + if let currentLanguageCode = currentLangCode { + FaceCaptureLanguageManager.shared.langCode = currentLanguageCode + } } override public func viewWillAppear(_ animated: Bool) { @@ -86,7 +92,7 @@ public class FaceCaptureController: UIViewController { queue: .main) { [weak self] _ in guard let self = self, self.alertView == nil else { return } - let alertView = AlertView(frame: self.view.bounds, text: NSLocalizedString("acuant_face_camera_paused", comment: "")) + let alertView = AlertView(frame: self.view.bounds, text: "acuant_face_camera_paused".localizedFaceCaptureString) self.view.addSubview(alertView) self.alertView = alertView } @@ -111,7 +117,7 @@ public class FaceCaptureController: UIViewController { if interfaceOrientation.isLandscape { self.alertView = AlertView(frame: self.view.frame, - text: NSLocalizedString("acuant_face_camera_rotate_portrait", comment: "")) + text: "acuant_face_camera_rotate_portrait".localizedFaceCaptureString) self.view.addSubview(self.alertView!) self.captureSession.stopRunning() } else if !captureSession.isRunning { @@ -334,7 +340,7 @@ public class FaceCaptureController: UIViewController { func addMessage(messageKey: String, color: CGColor? = UIColor.red.cgColor, fontSize: CGFloat = 30){ messageLayer.fontSize = fontSize messageLayer.foregroundColor = color - messageLayer.string = NSLocalizedString(messageKey, comment: "") + messageLayer.string = messageKey.localizedFaceCaptureString messageLayer.frame = getMessageRect() } @@ -355,10 +361,8 @@ public class FaceCaptureController: UIViewController { view.addSubview(backButton) NSLayoutConstraint.activate([ - backButton.widthAnchor.constraint(equalToConstant: 50), - backButton.heightAnchor.constraint(equalToConstant: 50), - backButton.topAnchor.constraint(equalTo: view.topAnchor, constant: 0), - backButton.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 0) + backButton.topAnchor.constraint(equalTo: view.topAnchor, constant: 15), + backButton.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -25) ]) } @@ -388,6 +392,7 @@ public class FaceCaptureController: UIViewController { func createMessageLayer() -> CATextLayer { messageLayer = CATextLayer() messageLayer.frame = getMessageRect() + messageLayer.isWrapped = true messageLayer.contentsScale = UIScreen.main.scale messageLayer.alignmentMode = CATextLayerAlignmentMode.center messageLayer.foregroundColor = UIColor.white.cgColor @@ -403,11 +408,55 @@ public class FaceCaptureController: UIViewController { } func getMessageRect() -> CGRect { + let sidePadding = 16.0 let width = view.safeAreaLayoutGuide.layoutFrame.size.width let topPadding = getSafeArea() let height = view.bounds.height * 0.17 let padding = topPadding == 0 ? (height - topPadding)/4 : topPadding - return CGRect(x: 0, y: padding, width: width, height: height) + return CGRect(x: sidePadding, y: padding, width: width - 2.0 * sidePadding, height: height) + } +} + + +// MARK: - Custom Localization + +open class FaceCaptureLanguageManager { + static let shared = FaceCaptureLanguageManager() + + var langCode: String? { + didSet { + if let appLanguage = langCode { + currentLanguage = appLanguage + } else { + currentLanguage = Locale.current.languageCode ?? "en" + } + } + } + + private(set) var currentLanguage: String + + private init() { + if let appLanguage = langCode { + currentLanguage = appLanguage + } else { + currentLanguage = Locale.current.languageCode ?? "en" + } + } + + public static func localizedString(_ key: String, comment: String = "") -> String { + let bundle = Bundle.main + guard let path = bundle.path(forResource: FaceCaptureLanguageManager.shared.currentLanguage, ofType: "lproj"), + let string = Bundle(path: path)?.localizedString(forKey: key, value: "", table: "") else { + return NSLocalizedString(key, comment: comment) + } + return string + } + +} + +extension String { + public var localizedFaceCaptureString: String { + return FaceCaptureLanguageManager.localizedString(self) } }