You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

635 lines
18 KiB

//
// UIExtension.swift
// GMERemittance
//
// Created by Sujal on 12/11/17.
// Copyright © 2017 Gobal Money Express Co. Ltd. All rights reserved.
//
import Foundation
import UIKit
import MBProgressHUD
import NVActivityIndicatorView
import ChannelIO
#if DEBUG
import FLEX
#endif
// MARK: - Navigation
extension UIViewController {
func setupPicturedNavBar(sideMenuAction: Selector? = nil) {
self.navigationController?.isNavigationBarHidden = false
self.navigationController?.navigationBar.isTranslucent = false
if let selector = sideMenuAction {
let leftButton = UIBarButtonItem(
image: UIImage(named: "ic_hamburger"),
style: .plain,
target: self,
action: selector
)
self.navigationItem.leftBarButtonItem = leftButton
} else {
self.navigationItem.leftBarButtonItem = nil
}
self.navigationController?.navigationBar.barTintColor = .themeRedDark
self.navigationController?.navigationBar.tintColor = .themeBlack
self.navigationItem.leftBarButtonItem?.tintColor = .white
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 125, height: 30))
imageView.contentMode = .scaleAspectFit
let image = UIImage(named: "ic_gme_new")?.withRenderingMode(.alwaysTemplate)
imageView.image = image
imageView.tintColor = .themeWhiteRed
self.navigationItem.titleView = imageView
}
func setupNormalNavigation(color: UIColor = .themeWhite) {
self.navigationController?.isNavigationBarHidden = false
self.navigationController?.navigationBar.backIndicatorImage = UIImage(named: "backIconBlack")
self.navigationController?.navigationBar
.backIndicatorTransitionMaskImage = UIImage(named: "backIconBlack")
self.navigationController?.navigationBar.titleTextAttributes = [
NSAttributedString.Key.font: UIFont.sanfrancisco(.medium, size: 17)
]
self.navigationController?.navigationBar.tintColor = .themeBlack
self.navigationController?.navigationBar.barTintColor = color
}
func setupNavigationShadow(isUse: Bool = true) {
navigationController?.navigationBar.setValue(!isUse, forKey: "hidesShadow")
}
}
// MARK: - Alert
extension UIViewController {
enum AlertType {
case success
case error
case normal
}
func alert(
type: AlertType = .normal,
message: String?,
title: String? = nil,
rightButtomTitle: String = "ok_text".localized(),
okAction: (() -> Void)? = nil
) {
let settedTitle: String
switch type {
case .normal:
settedTitle = title == nil ? "alert_text".localized() : title!
case .error:
settedTitle = title == nil ? "error_text".localized() : title!
case .success:
settedTitle = title == nil ? "success_text".localized() : title!
}
gmeAlert(
type: type,
title: settedTitle,
message: message,
rightButtonTitle: rightButtomTitle,
leftButtonTitle: nil,
rightButtonAction: okAction,
leftButtonAction: nil
)
}
func alertWithOkCancel(
type: AlertType = .normal,
message: String?,
title: String? = nil,
okTitle: String = "ok_text".localized(),
cancelTitle: String = "cancel_text".localized(),
okAction: (() -> Void)? = nil,
cancelAction: (() -> Void)? = nil
) {
let settedTitle: String
switch type {
case .normal:
settedTitle = title == nil ? "alert_text".localized() : title!
case .error:
settedTitle = title == nil ? "error_text".localized() : title!
case .success:
settedTitle = title == nil ? "success_text".localized() : title!
}
gmeAlert(
type: type,
title: settedTitle,
message: message,
rightButtonTitle: okTitle,
leftButtonTitle: cancelTitle,
rightButtonAction: okAction,
leftButtonAction: cancelAction
)
}
func alertWithOk(
type: AlertType = .normal,
message: String?,
title: String? = nil,
okTitle: String = "ok_text".localized(),
okAction: (() -> Void)? = nil
) {
let settedTitle: String
switch type {
case .normal:
settedTitle = title == nil ? "alert_text".localized() : title!
case .error:
settedTitle = title == nil ? "error_text".localized() : title!
case .success:
settedTitle = title == nil ? "success_text".localized() : title!
}
gmeAlert(
type: type,
title: settedTitle,
message: message,
rightButtonTitle: okTitle,
leftButtonTitle: nil,
rightButtonAction: okAction,
leftButtonAction: nil
)
}
private func getAlert(
type: AlertType,
message: String?,
title: String?,
style: UIAlertController.Style? = .alert
) -> UIAlertController {
let customerWalletNumber = GMEDB.shared.user.string(.walletNumber) ?? ""
let customerTitle: String
switch type {
case .error:
customerTitle = "\(title ?? "Alert")(\(customerWalletNumber))"
case .normal:
customerTitle = title ?? ""
case .success:
customerTitle = title ?? ""
}
return UIAlertController(title: customerTitle, message: message, preferredStyle: style ?? .alert)
}
func present(_ alert: UIAlertController, asActionsheetInSourceView sourceView: Any) {
if UI_USER_INTERFACE_IDIOM() == .pad {
alert.modalPresentationStyle = .popover
if let presenter = alert.popoverPresentationController {
if sourceView is UIBarButtonItem {
presenter.barButtonItem = sourceView as? UIBarButtonItem
} else if sourceView is UIView {
guard let view = sourceView as? UIView else {
return
}
presenter.sourceView = view
presenter.sourceRect = view.bounds
}
}
}
self.present(alert, animated: true, completion: nil)
}
func gmeAlert(
type: AlertType = .normal,
title: String = "Alert",
message: String? = nil,
rightButtonTitle: String = "Ok",
leftButtonTitle: String? = nil,
rightButtonAction: (() -> Void)? = nil,
leftButtonAction: (() -> Void)? = nil
) {
let titleText: String
let customerWalletNumber = GMEDB.shared.user.string(.walletNumber) ?? ""
switch type {
case .error:
if customerWalletNumber != "" {
titleText = "\(title) (\(customerWalletNumber))"
} else {
titleText = title
}
case .normal:
titleText = title
case .success:
titleText = title
}
let gmeAlertVC = GMEAlertViewController(
type: type,
title: titleText,
message: message,
rightButtonTitle: rightButtonTitle,
leftButtonTitle: leftButtonTitle,
rightButtonAction: rightButtonAction,
leftButtonAction: leftButtonAction
)
present(gmeAlertVC, animated: false, completion: nil)
}
}
extension UIAlertController {
func addAction(title: String?, style: UIAlertAction.Style = .default, handler: (() -> Void)? = nil) {
let action = UIAlertAction(title: title, style: style, handler: {_ in
handler?()
})
self.addAction(action)
}
}
struct Associate {
static var hud: UInt8 = 0
static var messageCount: UInt8 = 1
static var csButton: UInt8 = 2
static var channelIO: UInt8 = 3
}
// MARK: HUD
extension UIViewController {
private func setProgressHud() -> MBProgressHUD {
let progressHud: MBProgressHUD = MBProgressHUD.showAdded(to: self.view, animated: true)
progressHud.tintColor = UIColor.darkGray
progressHud.removeFromSuperViewOnHide = true
objc_setAssociatedObject(
self, &Associate.hud,
progressHud,
objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC
)
return progressHud
}
var progressHud: MBProgressHUD {
if let progressHud = objc_getAssociatedObject(self, &Associate.hud) as? MBProgressHUD {
progressHud.isUserInteractionEnabled = true
return progressHud
}
return setProgressHud()
}
var progressHudIsShowing: Bool {
return self.progressHud.isHidden
}
func showProgressHud(
backgroundColor: UIColor = .themeBackgroundGray,
loadingColor: UIColor = .themeRed,
textColor: UIColor = .white
) {
let activityData = ActivityData(
size: CGSize(width: 50, height: 50),
message: "loading_text".localized(),
messageFont: .sanfrancisco(.medium, size: 14),
messageSpacing: 2,
type: .lineScale,
color: loadingColor,
padding: 5,
backgroundColor: backgroundColor,
textColor: textColor
)
NVActivityIndicatorPresenter.sharedInstance.startAnimating(activityData, nil)
}
func hideProgressHud() {
NVActivityIndicatorPresenter.sharedInstance.stopAnimating(nil)
}
}
// MARK: - LargeTitle
extension UIViewController {
func setLargeTitle() {
if #available(iOS 11.0, *) {
self.navigationController?.navigationBar.prefersLargeTitles = true
self.navigationController?.navigationBar.largeTitleTextAttributes =
[NSAttributedString.Key.font: UIFont.sanfrancisco(.medium, size: 20)]
}
// UINavigationBar.appearance().titleTextAttributes =
// [NSAttributedStringKey.font: font]
}
}
// MARK: - Activity Indicator
private var associatedObjectHandle: UInt8 = 0
extension UIViewController {
private var progressView: UIView? {
get {
guard let view = objc_getAssociatedObject(self, &associatedObjectHandle) as? UIView else {
return nil
}
return view
}
set {
objc_setAssociatedObject(
self,
&associatedObjectHandle,
newValue,
objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC
)
}
}
func setPercent(with percent: CGFloat) {
let progressSubView: UIView
if let view = progressView {
progressSubView = view
} else {
progressSubView = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: 2))
progressView = progressSubView
}
progressSubView.removeFromSuperview()
view.addSubview(progressSubView)
print("progress: \(percent)")
progressSubView.backgroundColor = .themeRed
let width = view.frame.width * percent
UIView.animate(
withDuration: 0.5,
animations: {
progressSubView.frame = CGRect(x: 0, y: 0, width: width, height: 2)
},
completion: { _ in
if width == self.view.frame.width {
UIView.animate(
withDuration: 0.2,
animations: {
progressSubView.alpha = 0.0
},
completion: { _ in
progressSubView.frame = CGRect(x: 0, y: 0, width: 0, height: 2)
progressSubView.alpha = 1.0
})
}
}
)
}
}
// MARK: - Right Bar button item form ChannelIO
extension UIViewController {
@discardableResult
func setMessageCount(with count: Int = 0) -> Int {
objc_setAssociatedObject(
self, &Associate.messageCount,
count,
objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC
)
var appearance = BadgeAppearance()
let message = count != 0 ? "\(count)" : nil
appearance.backgroundColor = .themeWhiteRed
appearance.textColor = .themeRedWhite
csButton.badge(text: message, appearance: appearance)
return count
}
private var messageCount: Int {
guard let count = objc_getAssociatedObject(self, &Associate.messageCount) as? Int else {
let count = setMessageCount()
return count
}
return count
}
private func setCSButton() -> UIBarButtonItem {
let supportImage = UIImage(named: "ic_support")?.withRenderingMode(.alwaysOriginal)
let csButton = UIBarButtonItem(
image: supportImage,
style: .plain,
target: self,
action: #selector(UIViewController.touchCSButton)
)
objc_setAssociatedObject(
self, &Associate.csButton,
csButton,
objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC
)
return csButton
}
var csButton: UIBarButtonItem {
if let csButton = objc_getAssociatedObject(self, &Associate.csButton) as? UIBarButtonItem {
return csButton
}
return setCSButton()
}
@discardableResult
private func setChannelIODelegate(_ delegate: ChannelPluginDelegate? = nil) -> ChannelPluginDelegate? {
guard let delegate = delegate else { return nil }
objc_setAssociatedObject(
self, &Associate.channelIO,
delegate,
objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC
)
return delegate
}
var channelIODelegate: ChannelPluginDelegate? {
if let delegate = objc_getAssociatedObject(self, &Associate.channelIO) as? ChannelPluginDelegate {
return delegate
}
return setChannelIODelegate()
}
func addRightCSButton(delegate: ChannelPluginDelegate) {
setChannelIODelegate(delegate)
self.navigationItem.rightBarButtonItem = csButton
}
@objc func touchCSButton() {
let hotLines = HotLineService().staticHotLines
let nativeCountry = GMEDB.shared.user.string(.countryCode)?.lowercased()
let userHotLine = hotLines?.filter { $0.countryCode == nativeCountry }.first
let alert = UIAlertController(
title: nil,
message: "help_you_text".localized(),
preferredStyle: .actionSheet
)
let liveChat = UIAlertAction(
title: "live_chat_text".localized(),
style: .default
) { _ in
self.alertWithOkCancel(
message: "check_start_chat_text".localized(),
title: "check_start_chat_title_text".localized(),
okTitle: "yes_text".localized(),
cancelTitle: "no_text".localized(),
okAction: {
self.setChannelIO(delegate: self.channelIODelegate)
}
)
}
#if DEBUG
let debug = UIAlertAction(
title: "Debug",
style: .default
) { _ in
FLEXManager.shared()?.showExplorer()
}
let changeServer = UIAlertAction(
title: "Change Server (\(server.rawValue))",
style: .destructive
) { _ in
MainWireframe.shared?.window?.rootViewController = LauncherScreenWireframe().getMainView()
}
#endif
let contactNumber = UIAlertAction(
title: userHotLine?.remitPhoneNumber ?? "1588 6864",
style: .default
) { _ in
self.startCall(contactNumber: userHotLine?.remitPhoneNumber ?? "1588 6864")
}
liveChat.setValue(UIImage(named:"chat")?.withRenderingMode(.alwaysOriginal),forKey:"image")
contactNumber.setValue(UIImage(named:"ic_call")?.withRenderingMode(.alwaysOriginal),forKey:"image")
#if DEBUG
alert.addAction(changeServer)
alert.addAction(debug)
#endif
alert.addAction(liveChat)
alert.addAction(contactNumber)
alert.addAction(UIAlertAction(
title: "cancel_text".localized(),
style: UIAlertAction.Style.cancel,
handler: nil
)
)
alert.view.tintColor = .themeText
if UIDevice.current.userInterfaceIdiom == .pad {
if let popoverController = alert.popoverPresentationController {
popoverController.sourceView = self.view
popoverController.sourceRect = CGRect(
x: self.view.bounds.midX,
y: self.view.bounds.midY,
width: 0,
height: 0
)
popoverController.permittedArrowDirections = []
self.present(alert, animated: true, completion: nil)
}
} else {
self.present(alert, animated: true, completion: nil)
}
guard
let label = (liveChat.value(forKey: "__representer")as? NSObject)?.value(forKey: "label") as? UILabel
else { return }
var appearance = BadgeAppearance()
appearance.distanceFromCenterX = (label.intrinsicContentSize.width / 2) + 10
appearance.distanceFromCenterY = -(label.intrinsicContentSize.height / 2)
let message = messageCount != 0 ? "\(messageCount)" : nil
label.badge(text: message, appearance: appearance)
}
func setChannelIO(delegate: ChannelPluginDelegate?) {
let settings = ChannelPluginSettings()
settings.pluginKey = "24dc2dfd-3ed1-4953-b395-a2255ed41dae"
settings.userId = GMEDB.shared.user.string(.userId)
let profile = Profile()
let username = GMEDB.shared.user.string(.fullName)
let email = GMEDB.shared.user.string(.email)
profile
.set(name: username ?? "")
.set(email: email ?? "")
ChannelIO.delegate = delegate
ChannelIO.boot(with:settings, profile: profile) {(completion, _) in
var message = "channelIO_error_message_text".localized()
switch completion {
case .success:
ChannelIO.open(animated: true)
return
case .notInitialized: message += "(1)"
case .networkTimeout: message += "(2)"
case .notAvailableVersion: message += "(3)"
case .serviceUnderConstruction: message += "(4)"
case .requirePayment: message += "(5)"
case .accessDenied: message += "(6)"
case .unknown: message += "(7)"
@unknown default: message += "(8)"
}
self.alert(type: .error, message: message)
}
}
private func startCall(contactNumber: String) {
if let url = URL(string: "tel://\(contactNumber.removeWhitespacesInBetween())"),
UIApplication.shared.canOpenURL(url) {
UIApplication.shared.open(url)
}
}
}
extension UIViewController {
func presentDatePicker(completion: ((_ from: String?, _ to: String?) -> Void)?) {
guard let datePickerViewController = UIStoryboard
.init(name: "TransactionHistoryDatePicker", bundle: nil)
.instantiateViewController(
withIdentifier: "DatePickerViewController"
) as? DatePickerViewController else { return }
datePickerViewController.completion = completion
present(datePickerViewController, animated: true, completion: nil)
}
}