diff --git a/Trust.xcodeproj/project.pbxproj b/Trust.xcodeproj/project.pbxproj index 67af39762..3cc05f0c4 100644 --- a/Trust.xcodeproj/project.pbxproj +++ b/Trust.xcodeproj/project.pbxproj @@ -328,6 +328,7 @@ 5E7C774B5332AC0DC19C5B1B /* EthTokenViewCellViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C74B82783A94091A43470 /* EthTokenViewCellViewModel.swift */; }; 5E7C776BE1B19F824954962D /* BaseTicketTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7F5C10E3895E805EA7E0 /* BaseTicketTableViewCell.swift */; }; 5E7C776CF721EBBD43195926 /* GenerateSellMagicLinkViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C79CF6150E4CD4A276FC0 /* GenerateSellMagicLinkViewController.swift */; }; + 5E7C7788984F7ADCFE5B4DE0 /* AddressTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C75B5AF76279A71395FC7 /* AddressTextField.swift */; }; 5E7C7793AB6B577906F2BCA3 /* SettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7AFE9AF9FE6B58C925D4 /* SettingsViewController.swift */; }; 5E7C77A8425E0AFAB11F1FCD /* PromptBackupCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7ADD0FBE8708A6E98AF8 /* PromptBackupCoordinator.swift */; }; 5E7C77AD9FAAC18211B6F355 /* TransferTicketsQuantitySelectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7419F47CC8B2996AA8F9 /* TransferTicketsQuantitySelectionViewController.swift */; }; @@ -821,6 +822,7 @@ 5E7C755132D9B6F95080A1BE /* TransferTicketsCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransferTicketsCoordinator.swift; sourceTree = ""; }; 5E7C7564AF453BAB0BDAAA57 /* SettingsAction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsAction.swift; sourceTree = ""; }; 5E7C75918317E13AD540DCA7 /* RoundedBackground.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoundedBackground.swift; sourceTree = ""; }; + 5E7C75B5AF76279A71395FC7 /* AddressTextField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddressTextField.swift; sourceTree = ""; }; 5E7C75CC640BAFFE0E789F44 /* WalletFilterViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalletFilterViewModel.swift; sourceTree = ""; }; 5E7C75CE3F1D6B7993E7A840 /* OnboardingCollectionViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OnboardingCollectionViewController.swift; sourceTree = ""; }; 5E7C75F877B2F2E24C7EF258 /* TicketTableViewCellViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TicketTableViewCellViewModel.swift; sourceTree = ""; }; @@ -1299,6 +1301,7 @@ 29DF40091FD3E80A000077CA /* TabBarController.swift */, 442FC575B6A4A50B0555E1B0 /* NumberStepper.swift */, 5E7C75918317E13AD540DCA7 /* RoundedBackground.swift */, + 5E7C75B5AF76279A71395FC7 /* AddressTextField.swift */, ); path = UI; sourceTree = ""; @@ -3624,6 +3627,7 @@ 5E7C78F1D29280E3FF4EAF5E /* RoundedBackground.swift in Sources */, 5E7C7E68425E20834B898D06 /* Language.swift in Sources */, 5E7C7488D5CAE24B7462815A /* LiveLanguageSwitcherBundle.swift in Sources */, + 5E7C7788984F7ADCFE5B4DE0 /* AddressTextField.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Trust/Transfer/Coordinators/SendCoordinator.swift b/Trust/Transfer/Coordinators/SendCoordinator.swift index 775f439c7..31995a2a5 100644 --- a/Trust/Transfer/Coordinators/SendCoordinator.swift +++ b/Trust/Transfer/Coordinators/SendCoordinator.swift @@ -78,7 +78,7 @@ class SendCoordinator: Coordinator { } switch transferType { case .ether(let destination): - controller.targetAddressTextField.text = destination?.description + controller.targetAddressTextField.value = destination?.description ?? "" case .token: break case .stormBird: break case .stormBirdOrder: break diff --git a/Trust/Transfer/ViewControllers/SendViewController.swift b/Trust/Transfer/ViewControllers/SendViewController.swift index 1a1b8cba8..0a5868e88 100644 --- a/Trust/Transfer/ViewControllers/SendViewController.swift +++ b/Trust/Transfer/ViewControllers/SendViewController.swift @@ -22,7 +22,7 @@ protocol SendViewControllerDelegate: class { class SendViewController: UIViewController { let roundedBackground = RoundedBackground() let header = SendHeaderView() - let targetAddressTextField = UITextField() + let targetAddressTextField = AddressTextField() let amountTextField = UITextField() let alternativeAmountLabel = UILabel() let targetAddressLabel = UILabel() @@ -104,9 +104,7 @@ class SendViewController: UIViewController { targetAddressTextField.translatesAutoresizingMaskIntoConstraints = false targetAddressTextField.delegate = self - targetAddressTextField.returnKeyType = .next - targetAddressTextField.leftViewMode = .always - targetAddressTextField.rightViewMode = .always + targetAddressTextField.textField.returnKeyType = .next amountTextField.translatesAutoresizingMaskIntoConstraints = false amountTextField.delegate = self @@ -167,7 +165,6 @@ class SendViewController: UIViewController { targetAddressTextField.leadingAnchor.constraint(equalTo: roundedBackground.leadingAnchor, constant: 30), targetAddressTextField.trailingAnchor.constraint(equalTo: roundedBackground.trailingAnchor, constant: -30), - targetAddressTextField.heightAnchor.constraint(equalToConstant: ScreenChecker().isNarrowScreen() ? 30 : 50), amountTextField.leadingAnchor.constraint(equalTo: roundedBackground.leadingAnchor, constant: 30), amountTextField.trailingAnchor.constraint(equalTo: roundedBackground.trailingAnchor, constant: -30), @@ -215,9 +212,8 @@ class SendViewController: UIViewController { //Not good to rely on viewModel here on firstConfigure, which means if we change the padding on subsequent calls (which will probably never happen), it wouldn't be reflected. Unfortunately this needs to be here, otherwise while typing in the amount text field, the left and right views will move out of the text field momentarily amountTextField.leftView = .spacerWidth(viewModel.textFieldHorizontalPadding) amountTextField.rightView = makeAmountRightView() - targetAddressTextField.leftView = .spacerWidth(viewModel.textFieldHorizontalPadding) - targetAddressTextField.rightView = makeTargetAddressRightView() } + targetAddressTextField.configureOnce() changeQRCode(value: 0) @@ -226,11 +222,6 @@ class SendViewController: UIViewController { headerViewModel.showAlternativeAmount = viewModel.showAlternativeAmount header.configure(viewModel: headerViewModel) - targetAddressTextField.textColor = viewModel.textFieldTextColor - targetAddressTextField.font = viewModel.textFieldFont - targetAddressTextField.layer.borderColor = viewModel.textFieldBorderColor.cgColor - targetAddressTextField.layer.borderWidth = viewModel.textFieldBorderWidth - //targetAddressLabel.text = R.string.localizable.aSendRecipientAddressTitle() targetAddressLabel.font = viewModel.textFieldsLabelFont targetAddressLabel.textColor = viewModel.textFieldsLabelTextColor @@ -279,7 +270,6 @@ class SendViewController: UIViewController { } private func roundCornersBasedOnHeight() { - targetAddressTextField.layer.cornerRadius = targetAddressTextField.frame.size.height / 2 amountTextField.layer.cornerRadius = amountTextField.frame.size.height / 2 copyButton.cornerRadius = copyButton.frame.size.height / 2 } @@ -296,7 +286,7 @@ class SendViewController: UIViewController { } @objc func send() { - let addressString = targetAddressTextField.text?.trimmed ?? "" + let addressString = targetAddressTextField.value var amountString = "" if self.currentPair.left == viewModel.symbol { amountString = amountTextField.text?.trimmed ?? "" @@ -342,24 +332,6 @@ class SendViewController: UIViewController { self.delegate?.didPressConfirm(transaction: transaction, transferType: transferType, in: self) } - @objc func openReader() { - let controller = QRCodeReaderViewController() - controller.delegate = self - present(controller, animated: true, completion: nil) - } - - @objc func pasteAction() { - guard let value = UIPasteboard.general.string?.trimmed else { - return displayError(error: SendInputErrors.emptyClipBoard) - } - - guard CryptoAddressValidator.isValidAddress(value) else { - return displayError(error: Errors.invalidAddress) - } - targetAddressTextField.text = value - activateAmountView() - } - @objc func fiatAction(sender: UIButton) { let swappedPair = currentPair.swapPair() //New pair for future calculation we should swap pair each time we press fiat button. @@ -422,10 +394,6 @@ class SendViewController: UIViewController { updatePriceSection() } - private func addressTextFieldChanged(in range: NSRange, to string: String) -> Bool { - return true - } - private func amountTextFieldChanged(in range: NSRange, to string: String) -> Bool { guard let input = amountTextField.text else { return true @@ -504,26 +472,6 @@ class SendViewController: UIViewController { } } - private func makeTargetAddressRightView() -> UIView { - let pasteButton = Button(size: .normal, style: .borderless) - pasteButton.translatesAutoresizingMaskIntoConstraints = false - pasteButton.setTitle(R.string.localizable.sendPasteButtonTitle(), for: .normal) - pasteButton.titleLabel?.font = Fonts.regular(size: 14)! - pasteButton.setTitleColor(Colors.appGrayLabelColor, for: .normal) - pasteButton.addTarget(self, action: #selector(pasteAction), for: .touchUpInside) - - let scanQRCodeButton = Button(size: .normal, style: .borderless) - scanQRCodeButton.translatesAutoresizingMaskIntoConstraints = false - scanQRCodeButton.setImage(R.image.qr_code_icon(), for: .normal) - scanQRCodeButton.setTitleColor(Colors.appGrayLabelColor, for: .normal) - scanQRCodeButton.addTarget(self, action: #selector(openReader), for: .touchUpInside) - - let targetAddressRightView = [pasteButton, scanQRCodeButton].asStackView(distribution: .equalSpacing) - targetAddressRightView.translatesAutoresizingMaskIntoConstraints = false - - return targetAddressRightView - } - private func makeAmountRightView() -> UIView { let fiatButton = Button(size: .normal, style: .borderless) fiatButton.translatesAutoresizingMaskIntoConstraints = false @@ -568,7 +516,7 @@ extension SendViewController: QRCodeReaderDelegate { guard let result = QRURLParser.from(string: result) else { return } - targetAddressTextField.text = result.address + targetAddressTextField.value = result.address if let dataString = result.params["data"] { data = Data(hex: dataString.drop0x) @@ -588,9 +536,7 @@ extension SendViewController: QRCodeReaderDelegate { extension SendViewController: UITextFieldDelegate { func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { - if textField == targetAddressTextField { - return addressTextFieldChanged(in: range, to: string) - } else if textField == amountTextField { + if textField == amountTextField { return amountTextFieldChanged(in: range, to: string) } else { return true @@ -598,11 +544,30 @@ extension SendViewController: UITextFieldDelegate { } func textFieldShouldReturn(_ textField: UITextField) -> Bool { - if textField == targetAddressTextField { - activateAmountView() - } else if textField == amountTextField { + if textField == amountTextField { view.endEditing(true) } return true } } + +extension SendViewController: AddressTextFieldDelegate { + func displayError(error: Error, for: AddressTextField) { + displayError(error: error) + } + + func openQRCodeReader(for: AddressTextField) { + let controller = QRCodeReaderViewController() + controller.delegate = self + present(controller, animated: true, completion: nil) + } + + func didPaste(in: AddressTextField) { + activateAmountView() + } + + func shouldReturn(in: AddressTextField) -> Bool { + activateAmountView() + return true + } +} diff --git a/Trust/Transfer/ViewControllers/TransferTicketsViaWalletAddressViewController.swift b/Trust/Transfer/ViewControllers/TransferTicketsViaWalletAddressViewController.swift index cb559d8aa..7473aca1f 100644 --- a/Trust/Transfer/ViewControllers/TransferTicketsViaWalletAddressViewController.swift +++ b/Trust/Transfer/ViewControllers/TransferTicketsViaWalletAddressViewController.swift @@ -13,8 +13,7 @@ class TransferTicketsViaWalletAddressViewController: UIViewController { let roundedBackground = RoundedBackground() let header = TicketsViewControllerTitleHeader() let ticketView = TicketRowView() - let targetAddressLabel = UILabel() - let targetAddressTextField = UITextField() + let targetAddressTextField = AddressTextField() let nextButton = UIButton(type: .system) var viewModel: TransferTicketsViaWalletAddressViewControllerViewModel! var ticketHolder: TicketHolder @@ -31,11 +30,11 @@ class TransferTicketsViaWalletAddressViewController: UIViewController { roundedBackground.translatesAutoresizingMaskIntoConstraints = false view.addSubview(roundedBackground) + targetAddressTextField.label.translatesAutoresizingMaskIntoConstraints = false + targetAddressTextField.translatesAutoresizingMaskIntoConstraints = false targetAddressTextField.delegate = self - targetAddressTextField.returnKeyType = .done - targetAddressTextField.leftViewMode = .always - targetAddressTextField.rightViewMode = .always + targetAddressTextField.textField.returnKeyType = .done nextButton.setTitle(R.string.localizable.aWalletNextButtonTitle(), for: .normal) nextButton.addTarget(self, action: #selector(nextButtonTapped), for: .touchUpInside) @@ -47,7 +46,7 @@ class TransferTicketsViaWalletAddressViewController: UIViewController { header, ticketView, .spacer(height: 10), - targetAddressLabel, + targetAddressTextField.label, .spacer(height: ScreenChecker().isNarrowScreen() ? 2 : 4), targetAddressTextField, ].asStackView(axis: .vertical, alignment: .center) @@ -73,7 +72,6 @@ class TransferTicketsViaWalletAddressViewController: UIViewController { targetAddressTextField.leadingAnchor.constraint(equalTo: roundedBackground.leadingAnchor, constant: 30), targetAddressTextField.trailingAnchor.constraint(equalTo: roundedBackground.trailingAnchor, constant: -30), - targetAddressTextField.heightAnchor.constraint(equalToConstant: ScreenChecker().isNarrowScreen() ? 30 : 50), stackView.leadingAnchor.constraint(equalTo: roundedBackground.leadingAnchor), stackView.trailingAnchor.constraint(equalTo: roundedBackground.trailingAnchor), @@ -96,7 +94,7 @@ class TransferTicketsViaWalletAddressViewController: UIViewController { } @objc func nextButtonTapped() { - let address = targetAddressTextField.text?.trimmed ?? "" + let address = targetAddressTextField.value.trimmed delegate?.didEnterWalletAddress(ticketHolder: ticketHolder, to: address, paymentFlow: paymentFlow, in: self) } @@ -105,14 +103,8 @@ class TransferTicketsViaWalletAddressViewController: UIViewController { } func configure(viewModel: TransferTicketsViaWalletAddressViewControllerViewModel) { - let firstConfigure = self.viewModel == nil self.viewModel = viewModel - if firstConfigure { - targetAddressTextField.leftView = .spacerWidth(viewModel.textFieldHorizontalPadding) - targetAddressTextField.rightView = makeTargetAddressRightView() - } - view.backgroundColor = viewModel.backgroundColor header.configure(title: viewModel.headerTitle) @@ -135,65 +127,15 @@ class TransferTicketsViaWalletAddressViewController: UIViewController { ticketView.categoryLabel.text = viewModel.category - targetAddressTextField.textColor = viewModel.textFieldTextColor - targetAddressTextField.font = viewModel.textFieldFont - targetAddressTextField.layer.borderColor = viewModel.textFieldBorderColor.cgColor - targetAddressTextField.layer.borderWidth = viewModel.textFieldBorderWidth + targetAddressTextField.label.text = R.string.localizable.aSendRecipientAddressTitle() - targetAddressLabel.text = R.string.localizable.aSendRecipientAddressTitle() - targetAddressLabel.font = viewModel.textFieldsLabelFont - targetAddressLabel.textColor = viewModel.textFieldsLabelTextColor + targetAddressTextField.configureOnce() nextButton.setTitleColor(viewModel.buttonTitleColor, for: .normal) nextButton.backgroundColor = viewModel.buttonBackgroundColor nextButton.titleLabel?.font = viewModel.buttonFont } - override func viewDidLayoutSubviews() { - super.viewDidLayoutSubviews() - roundCornersBasedOnHeight() - } - - private func roundCornersBasedOnHeight() { - targetAddressTextField.layer.cornerRadius = targetAddressTextField.frame.size.height / 2 - } - - @objc func openReader() { - let controller = QRCodeReaderViewController() - controller.delegate = self - present(controller, animated: true, completion: nil) - } - - @objc func pasteAction() { - guard let value = UIPasteboard.general.string?.trimmed else { - return displayError(error: SendInputErrors.emptyClipBoard) - } - - guard CryptoAddressValidator.isValidAddress(value) else { - return displayError(error: Errors.invalidAddress) - } - targetAddressTextField.text = value - } - - private func makeTargetAddressRightView() -> UIView { - let pasteButton = Button(size: .normal, style: .borderless) - pasteButton.translatesAutoresizingMaskIntoConstraints = false - pasteButton.setTitle(R.string.localizable.sendPasteButtonTitle(), for: .normal) - pasteButton.titleLabel?.font = Fonts.regular(size: 14)! - pasteButton.setTitleColor(Colors.appGrayLabelColor, for: .normal) - pasteButton.addTarget(self, action: #selector(pasteAction), for: .touchUpInside) - - let scanQRCodeButton = Button(size: .normal, style: .borderless) - scanQRCodeButton.translatesAutoresizingMaskIntoConstraints = false - scanQRCodeButton.setImage(R.image.qr_code_icon(), for: .normal) - scanQRCodeButton.setTitleColor(Colors.appGrayLabelColor, for: .normal) - scanQRCodeButton.addTarget(self, action: #selector(openReader), for: .touchUpInside) - - let targetAddressRightView = [pasteButton, scanQRCodeButton].asStackView(distribution: .equalSpacing) - targetAddressRightView.translatesAutoresizingMaskIntoConstraints = false - - return targetAddressRightView - } } extension TransferTicketsViaWalletAddressViewController: QRCodeReaderDelegate { @@ -209,12 +151,26 @@ extension TransferTicketsViaWalletAddressViewController: QRCodeReaderDelegate { guard let result = QRURLParser.from(string: result) else { return } - targetAddressTextField.text = result.address + targetAddressTextField.value = result.address } } -extension TransferTicketsViaWalletAddressViewController: UITextFieldDelegate { - func textFieldShouldReturn(_ textField: UITextField) -> Bool { +extension TransferTicketsViaWalletAddressViewController: AddressTextFieldDelegate { + func displayError(error: Error, for: AddressTextField) { + displayError(error: error) + } + + func openQRCodeReader(for: AddressTextField) { + let controller = QRCodeReaderViewController() + controller.delegate = self + present(controller, animated: true, completion: nil) + } + + func didPaste(in: AddressTextField) { + //Do nothing + } + + func shouldReturn(in: AddressTextField) -> Bool{ view.endEditing(true) return true } diff --git a/Trust/Transfer/ViewModels/TransferTicketsViaWalletAddressViewControllerViewModel.swift b/Trust/Transfer/ViewModels/TransferTicketsViaWalletAddressViewControllerViewModel.swift index de664619a..da167aecc 100644 --- a/Trust/Transfer/ViewModels/TransferTicketsViaWalletAddressViewControllerViewModel.swift +++ b/Trust/Transfer/ViewModels/TransferTicketsViaWalletAddressViewControllerViewModel.swift @@ -54,29 +54,4 @@ struct TransferTicketsViaWalletAddressViewControllerViewModel { var date: String { return ticketHolder.date.formatAsShortDateString() } - var textFieldTextColor: UIColor { - return Colors.appText - } - var textFieldFont: UIFont { - if ScreenChecker().isNarrowScreen() { - return Fonts.light(size: 11)! - } else { - return Fonts.light(size: 15)! - } - } - var textFieldBorderColor: UIColor { - return Colors.appBackground - } - var textFieldBorderWidth: CGFloat { - return 1 - } - var textFieldHorizontalPadding: CGFloat { - return 22 - } - var textFieldsLabelTextColor: UIColor { - return Colors.appGrayLabelColor - } - var textFieldsLabelFont: UIFont { - return Fonts.regular(size: 10)! - } } diff --git a/Trust/UI/AddressTextField.swift b/Trust/UI/AddressTextField.swift new file mode 100644 index 000000000..bfbeb4a3c --- /dev/null +++ b/Trust/UI/AddressTextField.swift @@ -0,0 +1,116 @@ +// Copyright © 2018 Stormbird PTE. LTD. + +import UIKit + +protocol AddressTextFieldDelegate: class { + func displayError(error: Error, for: AddressTextField) + func openQRCodeReader(for: AddressTextField) + func didPaste(in: AddressTextField) + func shouldReturn(in: AddressTextField) -> Bool +} + +class AddressTextField: UIControl { + let label = UILabel() + let textField = UITextField() + var value: String { + get { + return textField.text ?? "" + } + set { + textField.text = newValue + } + } + var isConfigured = false + weak var delegate: AddressTextFieldDelegate? + + override init(frame: CGRect) { + super.init(frame: frame) + + textField.translatesAutoresizingMaskIntoConstraints = false + textField.delegate = self + textField.leftViewMode = .always + textField.rightViewMode = .always + addSubview(textField) + + NSLayoutConstraint.activate([ + textField.leadingAnchor.constraint(equalTo: leadingAnchor), + textField.trailingAnchor.constraint(equalTo: trailingAnchor), + textField.topAnchor.constraint(equalTo: topAnchor), + textField.bottomAnchor.constraint(equalTo: bottomAnchor), + heightAnchor.constraint(equalToConstant: ScreenChecker().isNarrowScreen() ? 30 : 50), + ]) + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func layoutSubviews() { + super.layoutSubviews() + roundCornersBasedOnHeight() + } + + private func roundCornersBasedOnHeight() { + textField.layer.cornerRadius = textField.frame.size.height / 2 + } + + func configureOnce() { + guard !isConfigured else { return } + isConfigured = true + + label.font = Fonts.regular(size: 10)! + label.textColor = Colors.appGrayLabelColor + + textField.leftView = .spacerWidth(22) + textField.rightView = makeTargetAddressRightView() + textField.textColor = Colors.appText + textField.font = ScreenChecker().isNarrowScreen() ? Fonts.light(size: 11)! : Fonts.light(size: 15)! + textField.layer.borderColor = Colors.appBackground.cgColor + textField.layer.borderWidth = 1 + } + + private func makeTargetAddressRightView() -> UIView { + let pasteButton = Button(size: .normal, style: .borderless) + pasteButton.translatesAutoresizingMaskIntoConstraints = false + pasteButton.setTitle(R.string.localizable.sendPasteButtonTitle(), for: .normal) + pasteButton.titleLabel?.font = Fonts.regular(size: 14)! + pasteButton.setTitleColor(Colors.appGrayLabelColor, for: .normal) + pasteButton.addTarget(self, action: #selector(pasteAction), for: .touchUpInside) + + let scanQRCodeButton = Button(size: .normal, style: .borderless) + scanQRCodeButton.translatesAutoresizingMaskIntoConstraints = false + scanQRCodeButton.setImage(R.image.qr_code_icon(), for: .normal) + scanQRCodeButton.setTitleColor(Colors.appGrayLabelColor, for: .normal) + scanQRCodeButton.addTarget(self, action: #selector(openReader), for: .touchUpInside) + + let targetAddressRightView = [pasteButton, scanQRCodeButton].asStackView(distribution: .equalSpacing) + targetAddressRightView.translatesAutoresizingMaskIntoConstraints = false + + return targetAddressRightView + } + + @objc func pasteAction() { + guard let value = UIPasteboard.general.string?.trimmed else { + delegate?.displayError(error: SendInputErrors.emptyClipBoard, for: self) + return + } + + guard CryptoAddressValidator.isValidAddress(value) else { + delegate?.displayError(error: Errors.invalidAddress, for: self) + return + } + self.value = value + delegate?.didPaste(in: self) + } + + @objc func openReader() { + delegate?.openQRCodeReader(for: self) + } +} + +extension AddressTextField: UITextFieldDelegate { + func textFieldShouldReturn(_ textField: UITextField) -> Bool { + guard let delegate = delegate else { return true } + return delegate.shouldReturn(in: self) + } +} diff --git a/TrustTests/Coordinators/SendCoordinatorTests.swift b/TrustTests/Coordinators/SendCoordinatorTests.swift index 21f23597b..34be7937c 100644 --- a/TrustTests/Coordinators/SendCoordinatorTests.swift +++ b/TrustTests/Coordinators/SendCoordinatorTests.swift @@ -33,7 +33,7 @@ class SendCoordinatorTests: XCTestCase { ) coordinator.start() - XCTAssertEqual(address.description, coordinator.sendViewController.targetAddressTextField.text) + XCTAssertEqual(address.description, coordinator.sendViewController.targetAddressTextField.value) XCTAssertTrue(coordinator.navigationController.viewControllers[0] is SendViewController) }