Implemented adding 'Done' button to keyboard as numeric keyboards don't have one -> keyboard cannot be dismissed

This commit is contained in:
dankito 2020-09-05 15:44:14 +02:00
parent 7bd6d750a4
commit c08b4e7b5d
4 changed files with 50 additions and 5 deletions

View File

@ -11,6 +11,8 @@ struct LabelledUIKitTextField: View {
var keyboardType: UIKeyboardType = .default var keyboardType: UIKeyboardType = .default
var autocapitalizationType: UITextAutocapitalizationType = .sentences var autocapitalizationType: UITextAutocapitalizationType = .sentences
var addDoneButton: Bool = false
var isPasswordField: Bool = false var isPasswordField: Bool = false
var focusOnStart = false var focusOnStart = false
@ -46,7 +48,9 @@ struct LabelledUIKitTextField: View {
Spacer() Spacer()
UIKitTextField(placeholder, text: $text, keyboardType: keyboardType, autocapitalizationType: autocapitalizationType, isPasswordField: isPasswordField, UIKitTextField(placeholder, text: $text,
keyboardType: keyboardType, autocapitalizationType: autocapitalizationType, addDoneButton: addDoneButton,
isPasswordField: isPasswordField,
focusOnStart: focusOnStart, focusNextTextFieldOnReturnKeyPress: focusNextTextFieldOnReturnKeyPress, focusTextField: focusTextFieldBinding, focusOnStart: focusOnStart, focusNextTextFieldOnReturnKeyPress: focusNextTextFieldOnReturnKeyPress, focusTextField: focusTextFieldBinding,
isFocusedChanged: isFocusedChanged, textAlignment: .right, isUserInputEnabled: isUserInputEnabled, isFocusedChanged: isFocusedChanged, textAlignment: .right, isUserInputEnabled: isUserInputEnabled,
actionOnReturnKeyPress: actionOnReturnKeyPress, textChanged: textChanged) actionOnReturnKeyPress: actionOnReturnKeyPress, textChanged: textChanged)

View File

@ -12,6 +12,8 @@ struct UIKitTextField: UIViewRepresentable {
private var keyboardType: UIKeyboardType = .default private var keyboardType: UIKeyboardType = .default
private var autocapitalizationType: UITextAutocapitalizationType = .sentences private var autocapitalizationType: UITextAutocapitalizationType = .sentences
private var addDoneButton: Bool = false
private var isPasswordField: Bool = false private var isPasswordField: Bool = false
private var focusOnStart = false private var focusOnStart = false
@ -28,16 +30,19 @@ struct UIKitTextField: UIViewRepresentable {
private var textChanged: ((String) -> Void)? = nil private var textChanged: ((String) -> Void)? = nil
init(_ titleKey: String, text: Binding<String>, keyboardType: UIKeyboardType = .default, autocapitalizationType: UITextAutocapitalizationType = .sentences, init(_ titleKey: String, text: Binding<String>, keyboardType: UIKeyboardType = .default, autocapitalizationType: UITextAutocapitalizationType = .sentences, addDoneButton: Bool = false,
isPasswordField: Bool = false, focusOnStart: Bool = false, focusNextTextFieldOnReturnKeyPress: Bool = false, focusTextField: Binding<Bool> = .constant(false), isPasswordField: Bool = false, focusOnStart: Bool = false, focusNextTextFieldOnReturnKeyPress: Bool = false, focusTextField: Binding<Bool> = .constant(false),
isFocusedChanged: ((Bool) -> Void)? = nil, isFocusedChanged: ((Bool) -> Void)? = nil,
textAlignment: NSTextAlignment = .natural, isUserInputEnabled: Bool = true, textAlignment: NSTextAlignment = .natural, isUserInputEnabled: Bool = true,
actionOnReturnKeyPress: (() -> Bool)? = nil, textChanged: ((String) -> Void)? = nil) { actionOnReturnKeyPress: (() -> Bool)? = nil, textChanged: ((String) -> Void)? = nil) {
self.placeholder = titleKey self.placeholder = titleKey
_text = text _text = text
self.keyboardType = keyboardType self.keyboardType = keyboardType
self.autocapitalizationType = autocapitalizationType self.autocapitalizationType = autocapitalizationType
self.addDoneButton = addDoneButton
self.isPasswordField = isPasswordField self.isPasswordField = isPasswordField
self.focusOnStart = focusOnStart self.focusOnStart = focusOnStart
@ -58,9 +63,14 @@ struct UIKitTextField: UIViewRepresentable {
textField.placeholder = placeholder.localize() textField.placeholder = placeholder.localize()
textField.isSecureTextEntry = isPasswordField
textField.keyboardType = keyboardType textField.keyboardType = keyboardType
textField.autocapitalizationType = autocapitalizationType textField.autocapitalizationType = autocapitalizationType
textField.isSecureTextEntry = isPasswordField
if addDoneButton {
addDoneButtonToKeyboard(textField, context.coordinator)
}
textField.delegate = context.coordinator textField.delegate = context.coordinator
@ -89,6 +99,21 @@ struct UIKitTextField: UIViewRepresentable {
} }
} }
private func addDoneButtonToKeyboard(_ textField: UITextField, _ coordinator: Coordinator) {
coordinator.textField = textField
let spacer = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: coordinator, action: #selector(coordinator.doneButtonTapped))
let doneToolbar: UIToolbar = UIToolbar(frame: CGRect.init(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 50))
doneToolbar.barStyle = .default
doneToolbar.items = [spacer, doneButton]
doneToolbar.sizeToFit()
textField.inputAccessoryView = doneToolbar
}
func makeCoordinator() -> UIKitTextField.Coordinator { func makeCoordinator() -> UIKitTextField.Coordinator {
return Coordinator(text: $text, focusNextTextFieldOnReturnKeyPress: focusNextTextFieldOnReturnKeyPress, isFocusedChanged: isFocusedChanged, return Coordinator(text: $text, focusNextTextFieldOnReturnKeyPress: focusNextTextFieldOnReturnKeyPress, isFocusedChanged: isFocusedChanged,
@ -110,6 +135,8 @@ struct UIKitTextField: UIViewRepresentable {
private var textChanged: ((String) -> Void)? private var textChanged: ((String) -> Void)?
var textField: UITextField? = nil
init(text: Binding<String>, focusNextTextFieldOnReturnKeyPress: Bool, isFocusedChanged: ((Bool) -> Void)? = nil, isUserInputEnabled: Bool, init(text: Binding<String>, focusNextTextFieldOnReturnKeyPress: Bool, isFocusedChanged: ((Bool) -> Void)? = nil, isUserInputEnabled: Bool,
actionOnReturnKeyPress: (() -> Bool)? = nil, textChanged: ((String) -> Void)? = nil) { actionOnReturnKeyPress: (() -> Bool)? = nil, textChanged: ((String) -> Void)? = nil) {
@ -153,6 +180,11 @@ struct UIKitTextField: UIViewRepresentable {
} }
func textFieldShouldReturn(_ textField: UITextField) -> Bool { func textFieldShouldReturn(_ textField: UITextField) -> Bool {
return handleReturnKeyPress(textField)
}
@discardableResult
func handleReturnKeyPress(_ textField: UITextField) -> Bool {
var didHandleReturnKey = actionOnReturnKeyPress?() ?? false var didHandleReturnKey = actionOnReturnKeyPress?() ?? false
if didHandleReturnKey == false && focusNextTextFieldOnReturnKeyPress == true { if didHandleReturnKey == false && focusNextTextFieldOnReturnKeyPress == true {
@ -171,6 +203,13 @@ struct UIKitTextField: UIViewRepresentable {
return didHandleReturnKey return didHandleReturnKey
} }
@objc
func doneButtonTapped() {
if let textField = self.textField {
handleReturnKeyPress(textField)
}
}
} }
} }

View File

@ -109,7 +109,8 @@ struct EnterTanDialog: View {
.padding(.vertical, 2) .padding(.vertical, 2)
Section { Section {
LabelledUIKitTextField(label: "Enter TAN:", text: $enteredTan, keyboardType: tanChallenge.tanProcedure.isNumericTan ? .numberPad : .default, autocapitalizationType: .none, actionOnReturnKeyPress: { LabelledUIKitTextField(label: "Enter TAN:", text: $enteredTan, keyboardType: tanChallenge.tanProcedure.isNumericTan ? .numberPad : .default,
autocapitalizationType: .none, addDoneButton: tanChallenge.tanProcedure.isNumericTan, actionOnReturnKeyPress: {
if self.isRequiredDataEntered() { if self.isRequiredDataEntered() {
self.enteringTanDone() self.enteringTanDone()
return true return true

View File

@ -146,7 +146,8 @@ struct TransferMoneyDialog: View {
} }
Section { Section {
LabelledUIKitTextField(label: "Amount", text: $amount, keyboardType: .decimalPad, focusNextTextFieldOnReturnKeyPress: true, actionOnReturnKeyPress: handleReturnKeyPress, textChanged: checkAndValidateEnteredAmount) LabelledUIKitTextField(label: "Amount", text: $amount, keyboardType: .decimalPad, addDoneButton: true,
focusNextTextFieldOnReturnKeyPress: true, actionOnReturnKeyPress: handleReturnKeyPress, textChanged: checkAndValidateEnteredAmount)
amountValidationResult.map { validationError in amountValidationResult.map { validationError in
ValidationLabel(validationError) ValidationLabel(validationError)