diff --git a/Sources/PrimerSDK/Classes/PCI/User Interface/Text Fields/PrimerCardNumberFieldView.swift b/Sources/PrimerSDK/Classes/PCI/User Interface/Text Fields/PrimerCardNumberFieldView.swift index 0438c4d14d..352890ae20 100644 --- a/Sources/PrimerSDK/Classes/PCI/User Interface/Text Fields/PrimerCardNumberFieldView.swift +++ b/Sources/PrimerSDK/Classes/PCI/User Interface/Text Fields/PrimerCardNumberFieldView.swift @@ -87,6 +87,21 @@ public final class PrimerCardNumberFieldView: PrimerTextFieldView { } primerTextField.text = newText.withoutWhiteSpace.separate(every: 4, with: " ") + + // Detect pasting of the card number + if string.count > 1 && (primerTextField.internalText?.count ?? 0) > 1 { + if let text = primerTextField.internalText { + + // Get the position of the last character in the string + if let endPosition = primerTextField.position(from: primerTextField.beginningOfDocument, offset: text.count) { + DispatchQueue.main.async { + // Create a UITextRange from the endPosition to endPosition (for placing the cursor at the end) + primerTextField.selectedTextRange = primerTextField.textRange(from: endPosition, to: endPosition) + } + } + } + } + return false } } diff --git a/Tests/Primer/UI/PrimerCardNumberFieldViewTests.swift b/Tests/Primer/UI/PrimerCardNumberFieldViewTests.swift index 124da9e013..df8b254439 100644 --- a/Tests/Primer/UI/PrimerCardNumberFieldViewTests.swift +++ b/Tests/Primer/UI/PrimerCardNumberFieldViewTests.swift @@ -116,4 +116,26 @@ final class PrimerCardNumberFieldViewTests: XCTestCase { waitForExpectations(timeout: 2.0) } + + func testCursorMovesToEndAfterPasting() throws { + view.text = "" + + // Simulate pasting a card number + _ = view.textField(view.textField, + shouldChangeCharactersIn: NSRange(location: 0, length: 0), + replacementString: "4242424242424242") + + // Add a small delay to ensure the cursor movement code has executed + let expectation = XCTestExpectation(description: "Wait for cursor to move") + + DispatchQueue.main.async { + // Check if the cursor is at the end of the text + let expectedPosition = self.view.textField.position(from: self.view.textField.endOfDocument, offset: 0) + XCTAssertEqual(self.view.textField.selectedTextRange?.start, expectedPosition) + + expectation.fulfill() + } + + wait(for: [expectation], timeout: 0.3) + } }