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.

554 lines
22 KiB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
  1. //
  2. // SetupRecipientViewController.swift
  3. // GME Remit
  4. //
  5. // Created by InKwon James Kim on 09/08/2019.
  6. //Copyright © 2019 Gobal Money Express Co. Ltd. All rights reserved.
  7. //
  8. import UIKit
  9. import RxSwift
  10. import RxCocoa
  11. enum DynamicFieldRequire: String {
  12. case mandatory = "M"
  13. case optional = "O"
  14. case hidden = "H"
  15. }
  16. class SetupRecipientViewController: UIViewController {
  17. // MARK: Properties
  18. var viewModel: SetupRecipientViewModel!
  19. weak var delegate: SetupRecipientDelegate?
  20. private var dynamicFieldDic: [String: ValidationTextField]?
  21. private let disposeBag = DisposeBag()
  22. // MARK: Computed Properties
  23. // MARK: IBOutlets
  24. @IBOutlet private weak var countryTextField: ValidationTextField!
  25. @IBOutlet private weak var paymentModeTextField: ValidationTextField!
  26. @IBOutlet private weak var countryContainerView: ShadowView!
  27. @IBOutlet private weak var recipientBankInfomationContainerView: UIView!
  28. @IBOutlet private weak var recipientInformationContainerView: UIStackView!
  29. @IBOutlet private weak var idContainerView: ShadowView!
  30. @IBOutlet private weak var addressContainerView: ShadowView!
  31. @IBOutlet private weak var otherContainerView: ShadowView!
  32. @IBOutlet private weak var bankTextField: ValidationTextField!
  33. @IBOutlet private weak var branchTextField: ValidationTextField!
  34. @IBOutlet private weak var accountTextField: ValidationTextField!
  35. @IBOutlet private weak var idTextField: ValidationTextField!
  36. @IBOutlet private weak var idNumberTextField: ValidationTextField!
  37. @IBOutlet private weak var firstNameTextField: ValidationTextField!
  38. @IBOutlet private weak var middleNameTextField: ValidationTextField!
  39. @IBOutlet private weak var lastNameTextField: ValidationTextField!
  40. @IBOutlet private weak var fullNameTextField: ValidationTextField!
  41. @IBOutlet private weak var firstNameLocalTextField: ValidationTextField!
  42. @IBOutlet private weak var middleNameLocalTextField: ValidationTextField!
  43. @IBOutlet private weak var lastNameLocalTextField: ValidationTextField!
  44. @IBOutlet private weak var fullNameLocalTextField: ValidationTextField!
  45. @IBOutlet private weak var nativeCountryTextField: ValidationTextField!
  46. @IBOutlet private weak var mobileTextField: ValidationTextField!
  47. @IBOutlet private weak var emailTextField: ValidationTextField!
  48. @IBOutlet private weak var stateProvinceTextField: ValidationTextField!
  49. @IBOutlet private weak var districtTextField: ValidationTextField!
  50. @IBOutlet private weak var cityTextField: ValidationTextField!
  51. @IBOutlet private weak var addressTextField: ValidationTextField!
  52. @IBOutlet private weak var relationTextField: ValidationTextField!
  53. @IBOutlet private weak var reasonTextField: ValidationTextField!
  54. @IBOutlet private weak var saveButton: UIButton!
  55. // MARK: VC's Life cycle
  56. override func viewDidLoad() {
  57. super.viewDidLoad()
  58. setup()
  59. }
  60. override func viewWillAppear(_ animated: Bool) {
  61. super.viewWillAppear(animated)
  62. title = "recipient_text".localized()
  63. setupNormalNavigation()
  64. }
  65. override func viewWillDisappear(_ animated: Bool) {
  66. super.viewWillDisappear(animated)
  67. view.endEditing(true)
  68. }
  69. // MARK: IBActions
  70. @IBAction func touchCloseButton(_ sender: UIBarButtonItem) {
  71. dismiss(animated: true, completion: nil)
  72. }
  73. }
  74. // MARK: Other Functions
  75. extension SetupRecipientViewController {
  76. private func setup() {
  77. // all setup should be done here
  78. countryContainerView.hero.id = "setupRecipient"
  79. countryContainerView.hero.modifiers = [.fade, .scale(0.2)]
  80. setUI()
  81. setMultiLanguage()
  82. setBinding()
  83. }
  84. private func setMultiLanguage() {
  85. countryTextField.titleText = "country_text".localized()
  86. nativeCountryTextField.titleText = "native_country_text".localized()
  87. paymentModeTextField.titleText = "payment_mode_text".localized()
  88. bankTextField.titleText = "bank_text".localized()
  89. branchTextField.titleText = "branch_text".localized()
  90. accountTextField.titleText = "account_text".localized()
  91. firstNameTextField.titleText = "first_name_text".localized()
  92. middleNameTextField.titleText = "middle_name_text".localized()
  93. lastNameTextField.titleText = "last_name_text".localized()
  94. fullNameTextField.titleText = "full_name_text".localized()
  95. firstNameLocalTextField.titleText = "first_name_local_text".localized()
  96. middleNameLocalTextField.titleText = "middle_name_local_text".localized()
  97. lastNameLocalTextField.titleText = "last_name_local_text".localized()
  98. fullNameLocalTextField.titleText = "full_name_local_text".localized()
  99. idTextField.titleText = "id_type_text".localized()
  100. idNumberTextField.titleText = "id_number_text".localized()
  101. mobileTextField.titleText = "mobile_text".localized()
  102. emailTextField.titleText = "email_text".localized()
  103. stateProvinceTextField.titleText = "state_province_text".localized()
  104. districtTextField.titleText = "district_text".localized()
  105. cityTextField.titleText = "city_text".localized()
  106. addressTextField.titleText = "address_text".localized()
  107. relationTextField.titleText = "relation_text".localized()
  108. reasonTextField.titleText = "reason_text".localized()
  109. countryTextField.placeholder = "country_placeholder_text".localized()
  110. nativeCountryTextField.placeholder = "native_country_placeholder_text".localized()
  111. paymentModeTextField.placeholder = "payment_mode_placeholder_text".localized()
  112. bankTextField.placeholder = "bank_placeholder_text".localized()
  113. branchTextField.placeholder = "branch_placeholder_text".localized()
  114. accountTextField.placeholder = "account_placeholder_text".localized()
  115. firstNameTextField.placeholder = "first_name_placeholder_text".localized()
  116. middleNameTextField.placeholder = "middle_name_placeholder_text".localized()
  117. lastNameTextField.placeholder = "last_name_placeholder_text".localized()
  118. fullNameTextField.placeholder = "full_name_placeholder_text".localized()
  119. firstNameLocalTextField.placeholder = "first_name_local_placeholder_text".localized()
  120. middleNameLocalTextField.placeholder = "middle_name_local_placeholder_text".localized()
  121. lastNameLocalTextField.placeholder = "last_name_local_placeholder_text".localized()
  122. fullNameLocalTextField.placeholder = "full_name_local_placeholder_text".localized()
  123. idTextField.placeholder = "id_type_placeholder_text".localized()
  124. idNumberTextField.placeholder = "id_number_placeholder_text".localized()
  125. mobileTextField.placeholder = "mobile_placeholder_text".localized()
  126. emailTextField.placeholder = "email_placeholder_text".localized()
  127. stateProvinceTextField.placeholder = "stateProvince_placeholder_text".localized()
  128. districtTextField.placeholder = "district_placeholder_text".localized()
  129. cityTextField.placeholder = "city_placeholder_text".localized()
  130. addressTextField.placeholder = "address_placeholder_text".localized()
  131. relationTextField.placeholder = "relation_placeholder_text".localized()
  132. reasonTextField.placeholder = "reason_placeholder_text".localized()
  133. saveButton.setTitle("save_text".localized(), for: .normal)
  134. }
  135. private func setSelectTextFields(of textFields: [UITextField]) {
  136. textFields.forEach {
  137. $0.inputView = UIView()
  138. $0.keyboardToolbar.isHidden = true
  139. }
  140. }
  141. private func setUI() {
  142. saveButton.layer.cornerRadius = 5
  143. countryTextField.statusImageView.isHidden = true
  144. paymentModeTextField.statusImageView.isHidden = true
  145. paymentModeTextField.isHidden = true
  146. paymentModeTextField.alpha = 0
  147. setSelectTextFields(of:[
  148. countryTextField, paymentModeTextField, bankTextField, branchTextField,
  149. idTextField, stateProvinceTextField, districtTextField, relationTextField, reasonTextField,
  150. nativeCountryTextField
  151. ]
  152. )
  153. recipientBankInfomationContainerView.isHidden = true
  154. recipientBankInfomationContainerView.alpha = 0
  155. recipientInformationContainerView.isHidden = true
  156. recipientInformationContainerView.alpha = 0
  157. recipientBankInfomationContainerView.travelSubView { (view, _) in
  158. if let textField = view as? ValidationTextField {
  159. textField.statusImageView.isHidden = true
  160. textField.isHidden = true
  161. }
  162. }
  163. recipientInformationContainerView.travelSubView { (view, _) in
  164. if let textField = view as? ValidationTextField {
  165. textField.statusImageView.isHidden = true
  166. textField.isHidden = true
  167. }
  168. }
  169. dynamicFieldDic = [
  170. "Bank Name": bankTextField,
  171. "Branch Name": branchTextField,
  172. "Account No.": accountTextField,
  173. "First Name": firstNameTextField,
  174. "Middle Name": middleNameTextField,
  175. "Last Name": lastNameTextField,
  176. "Full Name": fullNameTextField,
  177. "First Name in Local": firstNameLocalTextField,
  178. "Middle Name in Local": middleNameLocalTextField,
  179. "Last Name in Local": lastNameLocalTextField,
  180. "Local Name": fullNameLocalTextField,
  181. "Native Country": nativeCountryTextField,
  182. "Id Type": idTextField,
  183. "ID Number": idNumberTextField,
  184. "Mobile Number": mobileTextField,
  185. "Email": emailTextField,
  186. "Province": stateProvinceTextField,
  187. "District": districtTextField,
  188. "City": cityTextField,
  189. "Address": addressTextField,
  190. "Realation Group": relationTextField,
  191. "Transfer Reason": reasonTextField
  192. ]
  193. }
  194. private func setBinding() {
  195. let viewWillAppear = rx.sentMessage(#selector(UIViewController.viewWillAppear(_:)))
  196. .mapToVoid()
  197. .asDriverOnErrorJustComplete()
  198. let saveTrigger = saveButton.rx.tap.flatMap { [weak self] _ -> Observable<Recipient> in
  199. var recipient = Recipient()
  200. recipient.firstName = self?.firstNameTextField.text
  201. recipient.middleName = self?.middleNameTextField.text
  202. recipient.lastName = self?.lastNameTextField.text
  203. recipient.localFirstName = self?.firstNameLocalTextField.text
  204. recipient.localMiddleName = self?.middleNameLocalTextField.text
  205. recipient.localLastName = self?.lastNameLocalTextField.text
  206. recipient.fullName = self?.fullNameTextField.text
  207. recipient.localFullName = self?.fullNameLocalTextField.text
  208. recipient.address = self?.addressTextField.text
  209. recipient.city = self?.cityTextField.text
  210. recipient.email = self?.emailTextField.text
  211. recipient.mobile = self?.mobileTextField.mobileNumberText
  212. recipient.idNumber = self?.idNumberTextField.text
  213. recipient.agent?.accountNumber = self?.accountTextField.text
  214. return Observable.just(recipient)
  215. }.asDriverOnErrorJustComplete()
  216. let input = SetupRecipientViewModel.Input(
  217. initialTrigger: viewWillAppear,
  218. openCountryTrigger: countryTextField.rx.controlEvent(.editingDidBegin).asDriver(),
  219. openPaymentTrigger: paymentModeTextField.rx.controlEvent(.editingDidBegin).asDriver(),
  220. openBankTrigger: bankTextField.rx.controlEvent(.editingDidBegin).asDriver(),
  221. openBranchTrigger: branchTextField.rx.controlEvent(.editingDidBegin).asDriver(),
  222. openIDTypeTrigger: idTextField.rx.controlEvent(.editingDidBegin).asDriver(),
  223. openStateProvinceTrigger: stateProvinceTextField.rx.controlEvent(.editingDidBegin).asDriver(),
  224. openDistrictTrigger: districtTextField.rx.controlEvent(.editingDidBegin).asDriver(),
  225. openRelationTrigger: relationTextField.rx.controlEvent(.editingDidBegin).asDriver(),
  226. openReasonTrigger: reasonTextField.rx.controlEvent(.editingDidBegin).asDriver(),
  227. openNativeCountryTrigger: nativeCountryTextField.rx.controlEvent(.editingDidBegin).asDriver(),
  228. saveTrigger: saveTrigger
  229. )
  230. let output = viewModel.transform(input: input)
  231. output.isError
  232. .drive(onNext: { [weak self] in guard let `self` = self else { return }
  233. self.alert(type: .error, message: $0.localizedDescription)
  234. })
  235. .disposed(by: disposeBag)
  236. output.isProgress
  237. .drive(onNext: { [weak self] in guard let `self` = self else { return }
  238. $0 ? self.showProgressHud() : self.hideProgressHud()
  239. })
  240. .disposed(by: disposeBag)
  241. output.success
  242. .drive(onNext: { successObject in
  243. let message = "recipient_add_success_message_text".localized().replacingOccurrences(
  244. of: "xxx",
  245. with: successObject.data?.fullName ?? ""
  246. )
  247. self.alertWithOkCancel(
  248. type: .normal,
  249. message: "\(successObject.message ?? "")\n\(message)",
  250. title: "success_text".localized(),
  251. okTitle: "yes_text".localized(),
  252. cancelTitle: "no_text".localized(),
  253. okAction: { [weak self] in guard let `self` = self else { return }
  254. self.dismiss(animated: true) { [weak self] in guard let `self` = self else { return }
  255. self.delegate?.setupRecieient(
  256. self,
  257. didSelectRecipientID: successObject.data?.receiverID ?? ""
  258. )
  259. }
  260. },
  261. cancelAction: { [weak self] in guard let `self` = self else { return }
  262. self.dismiss(animated: true) { [weak self] in guard let `self` = self else { return }
  263. self.delegate?.setupRecieient(
  264. self,
  265. didSelectRecipientID: nil
  266. )
  267. }
  268. })
  269. }).disposed(by: disposeBag)
  270. bindUI(output: output)
  271. }
  272. private func bindUI(output: SetupRecipientViewModel.Output) {
  273. output.selectedRecipient
  274. .drive(onNext: { [weak self] in guard let `self` = self else { return }
  275. self.setText(with: $0)
  276. }).disposed(by: disposeBag)
  277. output.selectedCountry
  278. .drive(onNext: { [weak self] in guard let `self` = self else { return }
  279. guard let country = $0 else { return }
  280. self.countryTextField.text = country.countryName
  281. self.countryTextField.setCountry(with: country.countryCode, isShowCode: false)
  282. self.countryTextField.sendActions(for: .editingChanged)
  283. self.mobileTextField.setCountry(with: country.countryCode)
  284. self.paymentModeTextField.animateHidden(isHidden: false, duration: 0.5)
  285. self.recipientBankInfomationContainerView.animateHidden(isHidden: true, duration: 0.5)
  286. self.recipientInformationContainerView.animateHidden(isHidden: true, duration: 0.5)
  287. }).disposed(by: disposeBag)
  288. output.selectedPaymentMode.drive(onNext: { [weak self] in guard let `self` = self else { return }
  289. self.paymentModeTextField.text = $0?.subtitle
  290. self.paymentModeTextField.sendActions(for: .editingChanged)
  291. }).disposed(by: disposeBag)
  292. output.selectedBank.drive(onNext: { [weak self] in guard let `self` = self else { return }
  293. self.bankTextField.text = $0?.name
  294. self.bankTextField.sendActions(for: .editingChanged)
  295. if $0?.branchRequired?.lowercased() == "false" {
  296. self.branchTextField.isHidden = true
  297. self.branchTextField.text = ""
  298. self.branchTextField.valid.onNext(true)
  299. } else {
  300. self.branchTextField.isHidden = false
  301. self.branchTextField.valid.onNext(false)
  302. }
  303. if $0?.accountRequired?.lowercased() == "false" {
  304. self.accountTextField.isHidden = true
  305. self.accountTextField.text = ""
  306. self.accountTextField.valid.onNext(true)
  307. } else {
  308. self.accountTextField.isHidden = false
  309. if self.accountTextField.text != "" {
  310. self.accountTextField.valid.onNext(true)
  311. } else {
  312. self.accountTextField.valid.onNext(false)
  313. }
  314. }
  315. }).disposed(by: disposeBag)
  316. output.selectedBranch.drive(onNext: { [weak self] in guard let `self` = self else { return }
  317. self.branchTextField.text = $0?.name
  318. self.branchTextField.sendActions(for: .editingChanged)
  319. }).disposed(by: disposeBag)
  320. output.selectedIDType.drive(onNext: { [weak self] in guard let `self` = self else { return }
  321. self.idTextField.text = $0?.text
  322. self.idTextField.sendActions(for: .editingChanged)
  323. }).disposed(by: disposeBag)
  324. output.selectedStateProvince.drive(onNext: { [weak self] in guard let `self` = self else { return }
  325. self.stateProvinceTextField.text = $0?.name
  326. self.stateProvinceTextField.sendActions(for: .editingChanged)
  327. let count = $0?.districts?.count ?? 0
  328. if count == 0 {
  329. self.districtTextField.isHidden = true
  330. self.districtTextField.valid.onNext(true)
  331. } else {
  332. self.districtTextField.isHidden = false
  333. self.districtTextField.valid.onNext(false)
  334. }
  335. }).disposed(by: disposeBag)
  336. output.selectedDistrict.drive(onNext: { [weak self] in guard let `self` = self else { return }
  337. self.districtTextField.text = $0?.name
  338. self.districtTextField.sendActions(for: .editingChanged)
  339. }).disposed(by: disposeBag)
  340. output.selectedRelation.drive(onNext: { [weak self] in guard let `self` = self else { return }
  341. self.relationTextField.text = $0?.title
  342. self.relationTextField.sendActions(for: .editingChanged)
  343. }).disposed(by: disposeBag)
  344. output.selectedReason.drive(onNext: { [weak self] in guard let `self` = self else { return }
  345. self.reasonTextField.text = $0?.title
  346. self.reasonTextField.sendActions(for: .editingChanged)
  347. }).disposed(by: disposeBag)
  348. output.selectedNativeCountry.drive(onNext: { [weak self] in guard let `self` = self else { return }
  349. self.nativeCountryTextField.text = $0?.text
  350. self.nativeCountryTextField.sendActions(for: .editingChanged)
  351. }).disposed(by: disposeBag)
  352. output.models.dynamicFieldsModel.drive(onNext: { [weak self] in guard let `self` = self else { return }
  353. self.setDynamicFields(dynamicFieldInfo: $0)
  354. self.recipientBankInfomationContainerView.animateHidden(isHidden: false, duration: 0.5)
  355. self.recipientInformationContainerView.animateHidden(isHidden: false, duration: 0.5)
  356. }).disposed(by: disposeBag)
  357. }
  358. private func setDynamicFields(dynamicFieldInfo: [FieldModel]?) {
  359. dynamicFieldInfo?.forEach { [weak self] property in
  360. guard let `self` = self else { return }
  361. guard
  362. let key = property.fieldName,
  363. let textField = self.dynamicFieldDic?[key],
  364. let isRequire = DynamicFieldRequire(rawValue: property.required ?? ""),
  365. let min = property.minLength,
  366. let max = property.maxLength,
  367. let keyboardType = property.keyBoardType else { return }
  368. textField.errorMessage = "general_length_error_text".localized().replacingOccurrences(
  369. of: "xxx",
  370. with: "\(min)"
  371. ).replacingOccurrences(of: "ooo", with: "\(max)")
  372. switch isRequire {
  373. case .mandatory:
  374. textField.isHidden = false
  375. if max == min && min == -1 {
  376. textField.validCondition = { !$0.isEmpty }
  377. textField.errorMessage = nil
  378. } else {
  379. textField.validCondition = { ($0.count >= min && $0.count <= max) && !$0.isEmpty }
  380. }
  381. case .optional:
  382. textField.isHidden = false
  383. if max == min && min == -1 {
  384. textField.validCondition = nil
  385. textField.errorMessage = nil
  386. } else {
  387. textField.validCondition = { ($0.count >= min && $0.count <= max) }
  388. }
  389. if !textField.titleText.contains("optional_hint_text".localized()) {
  390. textField.titleText += "optional_hint_text".localized()
  391. textField.placeholder = "\(textField.placeholder ?? "") \("optional_hint_text".localized())"
  392. }
  393. case .hidden:
  394. textField.isHidden = true
  395. textField.text = ""
  396. }
  397. if key.contains("Local") {
  398. textField.keyboardType = .default
  399. } else {
  400. let keyType = GMEKeyboardType(rawValue: keyboardType) ?? GMEKeyboardType.alphabetNumbericSpecial
  401. switch keyType {
  402. case .numberic: textField.keyboardType = .numberPad
  403. default: textField.keyboardType = .asciiCapable
  404. }
  405. textField.rx.controlEvent(.editingChanged).asDriver()
  406. .drive(onNext: { _ in
  407. switch keyType {
  408. case .numberic: textField.fitlerBy(type: .alphabetNumberic, isSendAction: false)
  409. default: textField.fitlerBy(type: keyType, isSendAction: false)
  410. }
  411. }).disposed(by: disposeBag)
  412. }
  413. }
  414. guard let isValids = self.dynamicFieldDic?.values.filter({!$0.isHidden}).compactMap({$0.valid})
  415. else {return}
  416. Observable
  417. .combineLatest(isValids).flatMap {
  418. Observable.just($0.allSatisfy {$0})
  419. }
  420. .bind { [weak self] in guard let `self` = self else { return }
  421. self.saveButton.isEnabled = $0
  422. self.saveButton.backgroundColor = $0 ? .themeRed : .lightGray
  423. }
  424. .disposed(by: disposeBag)
  425. idContainerView.isHidden = idTextField.isHidden && idNumberTextField.isHidden
  426. addressContainerView.isHidden = stateProvinceTextField.isHidden &&
  427. districtTextField.isHidden &&
  428. cityTextField.isHidden &&
  429. addressTextField.isHidden
  430. otherContainerView.isHidden = mobileTextField.isHidden &&
  431. emailTextField.isHidden &&
  432. relationTextField.isHidden &&
  433. reasonTextField.isHidden
  434. }
  435. private func setText(with recipient: Recipient?) {
  436. fullNameTextField.text = recipient?.fullName
  437. fullNameTextField.sendActions(for: .editingChanged)
  438. firstNameTextField.text = recipient?.firstName
  439. firstNameTextField.sendActions(for: .editingChanged)
  440. middleNameTextField.text = recipient?.middleName
  441. middleNameTextField.sendActions(for: .editingChanged)
  442. lastNameTextField.text = recipient?.lastName
  443. lastNameTextField.sendActions(for: .editingChanged)
  444. fullNameLocalTextField.text = recipient?.localFullName
  445. fullNameLocalTextField.sendActions(for: .editingChanged)
  446. firstNameLocalTextField.text = recipient?.localFirstName
  447. firstNameLocalTextField.sendActions(for: .editingChanged)
  448. middleNameLocalTextField.text = recipient?.localMiddleName
  449. middleNameLocalTextField.sendActions(for: .editingChanged)
  450. lastNameLocalTextField.text = recipient?.localLastName
  451. lastNameLocalTextField.sendActions(for: .editingChanged)
  452. accountTextField.text = recipient?.agent?.accountNumber
  453. accountTextField.sendActions(for: .editingChanged)
  454. idNumberTextField.text = recipient?.idNumber
  455. idNumberTextField.sendActions(for: .editingChanged)
  456. emailTextField.text = recipient?.email
  457. emailTextField.sendActions(for: .editingChanged)
  458. mobileTextField.setCoutryFlag(with: recipient?.countryCode)
  459. mobileTextField.mobileNumberText = recipient?.mobile
  460. mobileTextField.sendActions(for: .editingChanged)
  461. addressTextField.text = recipient?.address
  462. addressTextField.sendActions(for: .editingChanged)
  463. cityTextField.text = recipient?.city
  464. cityTextField.sendActions(for: .editingChanged)
  465. }
  466. }