diff --git a/ui/BankingiOSApp/BankingiOSApp/ui/UIKitTextField.swift b/ui/BankingiOSApp/BankingiOSApp/ui/UIKitTextField.swift index b9963d88..4717535e 100644 --- a/ui/BankingiOSApp/BankingiOSApp/ui/UIKitTextField.swift +++ b/ui/BankingiOSApp/BankingiOSApp/ui/UIKitTextField.swift @@ -18,11 +18,13 @@ struct UIKitTextField: UIViewRepresentable { private var actionOnReturnKeyPress: (() -> Bool)? = nil + private var textChanged: ((String) -> Void)? = nil + @State private var textField: UITextField? = nil init(_ titleKey: String, text: Binding, keyboardType: UIKeyboardType = .default, isPasswordField: Bool = false, - focusOnStart: Bool = false, focusNextTextFieldOnReturnKeyPress: Bool = false, actionOnReturnKeyPress: (() -> Bool)? = nil) { + focusOnStart: Bool = false, focusNextTextFieldOnReturnKeyPress: Bool = false, actionOnReturnKeyPress: (() -> Bool)? = nil, textChanged: ((String) -> Void)? = nil) { self.placeHolder = titleKey _text = text @@ -33,6 +35,7 @@ struct UIKitTextField: UIViewRepresentable { self.focusNextTextFieldOnReturnKeyPress = focusNextTextFieldOnReturnKeyPress self.actionOnReturnKeyPress = actionOnReturnKeyPress + self.textChanged = textChanged } @@ -69,7 +72,7 @@ struct UIKitTextField: UIViewRepresentable { func makeCoordinator() -> UIKitTextField.Coordinator { - return Coordinator(text: $text, focusNextTextFieldOnReturnKeyPress: focusNextTextFieldOnReturnKeyPress, actionOnReturnKeyPress: actionOnReturnKeyPress) + return Coordinator(text: $text, focusNextTextFieldOnReturnKeyPress: focusNextTextFieldOnReturnKeyPress, actionOnReturnKeyPress: actionOnReturnKeyPress, textChanged: textChanged) } @@ -89,19 +92,30 @@ struct UIKitTextField: UIViewRepresentable { private var focusNextTextFieldOnReturnKeyPress: Bool private var actionOnReturnKeyPress: (() -> Bool)? + + private var textChanged: ((String) -> Void)? - init(text: Binding, focusNextTextFieldOnReturnKeyPress: Bool, actionOnReturnKeyPress: (() -> Bool)? = nil) { + init(text: Binding, focusNextTextFieldOnReturnKeyPress: Bool, actionOnReturnKeyPress: (() -> Bool)? = nil, textChanged: ((String) -> Void)? = nil) { _text = text self.focusNextTextFieldOnReturnKeyPress = focusNextTextFieldOnReturnKeyPress self.actionOnReturnKeyPress = actionOnReturnKeyPress + + self.textChanged = textChanged } func textFieldDidChangeSelection(_ textField: UITextField) { + let newText = textField.text ?? "" + let didTextChange = newText != text // e.g. if just the cursor has been placed to another position then textFieldDidChangeSelection() gets called but text didn't change + DispatchQueue.main.async { // to not update state during view update - self.text = textField.text ?? "" + self.text = newText + + if didTextChange { + self.textChanged?(newText) + } } } diff --git a/ui/BankingiOSApp/BankingiOSApp/ui/views/EnterTanDialog.swift b/ui/BankingiOSApp/BankingiOSApp/ui/views/EnterTanDialog.swift index a54cc378..2407bb6e 100644 --- a/ui/BankingiOSApp/BankingiOSApp/ui/views/EnterTanDialog.swift +++ b/ui/BankingiOSApp/BankingiOSApp/ui/views/EnterTanDialog.swift @@ -128,14 +128,14 @@ struct EnterTanDialog: View { .padding(.vertical, 2) Section { - UIKitTextField("Enter TAN:", text: $enteredTan) { + UIKitTextField("Enter TAN:", text: $enteredTan, actionOnReturnKeyPress: { if self.isRequiredDataEntered() { self.enteringTanDone() return true } return false - } + }) } Section { diff --git a/ui/BankingiOSApp/BankingiOSApp/ui/views/TransferMoneyDialog.swift b/ui/BankingiOSApp/BankingiOSApp/ui/views/TransferMoneyDialog.swift index 4c2d5970..56f17dac 100644 --- a/ui/BankingiOSApp/BankingiOSApp/ui/views/TransferMoneyDialog.swift +++ b/ui/BankingiOSApp/BankingiOSApp/ui/views/TransferMoneyDialog.swift @@ -90,8 +90,7 @@ struct TransferMoneyDialog: View { } Section { - UIKitTextField("Remittee Name", text: $remitteeName, focusOnStart: true, focusNextTextFieldOnReturnKeyPress: true, actionOnReturnKeyPress: handleReturnKeyPress) - .onReceive(Just(remitteeName)) { newValue in + UIKitTextField("Remittee Name", text: $remitteeName, focusOnStart: true, focusNextTextFieldOnReturnKeyPress: true, actionOnReturnKeyPress: handleReturnKeyPress) { newValue in self.isValidRemitteeNameEntered = self.remitteeName.isNotBlank } @@ -105,16 +104,14 @@ struct TransferMoneyDialog: View { } } - UIKitTextField("Remittee IBAN", text: $remitteeIban, focusNextTextFieldOnReturnKeyPress: true, actionOnReturnKeyPress: handleReturnKeyPress) - .onReceive(Just(remitteeIban)) { newValue in + UIKitTextField("Remittee IBAN", text: $remitteeIban, focusNextTextFieldOnReturnKeyPress: true, actionOnReturnKeyPress: handleReturnKeyPress) { newValue in self.isValidRemitteeIbanEntered = newValue.count > 14 // TODO: implement real check if IBAN is valid self.tryToGetBicFromIban(newValue) } } Section { - UIKitTextField("Amount", text: $amount, keyboardType: .decimalPad, focusNextTextFieldOnReturnKeyPress: true, actionOnReturnKeyPress: handleReturnKeyPress) - .onReceive(Just(amount)) { newValue in + UIKitTextField("Amount", text: $amount, keyboardType: .decimalPad, focusNextTextFieldOnReturnKeyPress: true, actionOnReturnKeyPress: handleReturnKeyPress) { newValue in // TODO: implement DecimalTextField / NumericTextField let filtered = newValue.filter { "0123456789,".contains($0) } if filtered != newValue { @@ -124,8 +121,7 @@ struct TransferMoneyDialog: View { self.isValidAmountEntered = self.amount.isNotBlank } - UIKitTextField("Usage", text: $usage, actionOnReturnKeyPress: handleReturnKeyPress) - .onReceive(Just($usage)) { newValue in + UIKitTextField("Usage", text: $usage, actionOnReturnKeyPress: handleReturnKeyPress) { newValue in self.isValidUsageEntered = true } } @@ -141,7 +137,7 @@ struct TransferMoneyDialog: View { Spacer() Button(action: { self.transferMoney() }, label: { Text("Transfer Money") }) - .disabled(!self.isRequiredDataEntered()) + .disabled( !self.isRequiredDataEntered()) Spacer() } }