2
votes

Est-il possible de changer la touche «retour» en «terminé» sur le clavier en 2020 avec SwiftUI?

Je n'ai trouvé aucun lien ou guide pour changer la touche «retour» en «terminé» lorsque le clavier est ouvert pour TextField dans SwiftUI.

Est-ce possible maintenant sans personnaliser UITextField?


4 commentaires

Est-ce que cela répond à votre question? Changez la fonction du bouton 'Retour' en 'Terminé' dans swift dans UITextView


Non, ils utilisent UIKit et je cherche une réponse pour SwiftUI


Je recherche stackoverflow.com/questions/58121756/... mais sans UIKit.


Passez à la réponse de Ty Irvine ci-dessous, de loin la solution la plus simple à mon avis


3 Réponses :


4
votes

Si quelqu'un cherche à envelopper UITextField dans UIViewRepresentable, j'ai du code à partager:

struct CustomTextField: UIViewRepresentable {

    let tag: Int
    let placeholder: String
    let keyboardType: UIKeyboardType
    let returnVal: UIReturnKeyType

    @Binding var text: String
    @Binding var activeFieldTag: Int?
    var totalFields: Int = 0
    @Binding var isSecureTextEntry: Bool
    var textColor: UIColor = .pureWhite
    var font: UIFont = .nexaBold13
    var placeholderTextColor: UIColor = .pureWhite
    var placeholderFont: UIFont = .nexaLight13
    var onEditingChanged: (Bool) -> Void = { _ in }

    var lastActiveFieldTag: Int? {

        // Return, if no active field
        // (It also means textFieldShouldReturn not called yet OR called for last field)
        guard let activeFieldTag = activeFieldTag else {
            return nil
        }
        // Return previous field
        if activeFieldTag > 0 {
            return activeFieldTag - 1
        }
        // Return, if no previous field
        return nil
    }

    func makeUIView(context: Context) -> UITextField {
        let textField = UITextField(frame: .zero)
        textField.keyboardType = self.keyboardType
        textField.returnKeyType = self.returnVal
        textField.tag = self.tag
        textField.textColor = textColor
        textField.font = font
        textField.attributedPlaceholder = NSAttributedString(
            string: self.placeholder,
            attributes: [
                NSAttributedString.Key.foregroundColor: placeholderTextColor,
                NSAttributedString.Key.font: placeholderFont,
            ]
        )
        textField.delegate = context.coordinator
        textField.autocorrectionType = .no
        textField.isSecureTextEntry = isSecureTextEntry
        return textField
    }

    func updateUIView(_ textField: UITextField, context: Context) {
        if textField.text != self.text {
            textField.text = self.text
        }
        handleFirstResponder(textField)
        if textField.isSecureTextEntry != isSecureTextEntry {
            textField.isSecureTextEntry = isSecureTextEntry
        }
    }

    func handleFirstResponder(_ textField: UITextField) {

        // return if field is neither active nor last-active
        if tag != lastActiveFieldTag && tag != activeFieldTag {
            return
        }

        // return if field is already active
        if lastActiveFieldTag == activeFieldTag {
            return
        }

        // It creates problem in UI when we press the next button too fast and continuously on keyboard
        //        // Remove focus from last active field
        //        if lastActiveFieldTag == tag {
        //            uiView.removeFocus()
        //            return
        //        }

        // Give focus to active field
        if activeFieldTag == tag {
            textField.focus()
            return
        }
    }

    // Its called when pressing Next button on the keyboard
    // See textFieldShouldReturn
    func updateNextTag() {
        // There is no next field so set activeFieldTag to nil
        if tag + 1 == totalFields {
            activeFieldTag = nil
        } else {
            // Set next field tag as active
            activeFieldTag = tag + 1
        }
    }

    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    class Coordinator: NSObject, UITextFieldDelegate {

        var parent: CustomTextField

        init(_ textField: CustomTextField) {
            self.parent = textField
        }

        func updatefocus(textfield: UITextField) {
            textfield.focus()
        }

        func textFieldShouldReturn(_ textField: UITextField) -> Bool {

            // Give focus to next field
            parent.updateNextTag()
            parent.text = textField.text ?? ""

            // If there is no next active field then dismiss the keyboard
            if parent.activeFieldTag == nil {
                DispatchQueue.main.async {
                    textField.removeFocus()
                }
            } 

            return true
        }

        func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
            DispatchQueue.main.async {
                // To enable user to click on any textField while another is active
                self.parent.activeFieldTag = self.parent.tag
                self.parent.onEditingChanged(true)
            }
            return true
        }

        func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
            self.parent.text = textField.text ?? ""
            DispatchQueue.main.async {
                self.parent.onEditingChanged(false)
            }
            return true
        }

        func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
            if let text = textField.text, let rangeExp = Range(range, in: text) {
                self.parent.text = text.replacingCharacters(in: rangeExp, with: string)
            }
            return true
        }
    }
}


1 commentaires

Pourquoi est-ce que Type 'UIColor' has no member 'pureWhite' erreurs indiquant que le Type 'UIColor' has no member 'pureWhite' et que la valeur de type «UITextField» n'a pas de membre «focus»? Quelque chose a changé



2
votes

Pour obtenir le bouton go sur le clavier. Essayez de changer le type de clavier en .webSearch.

// Testé sur Xcode 12 beta 2 et iOS 14

.keyboardType (.webSearch)


0 commentaires

3
votes

Le meilleur moyen que j'ai trouvé était d'ajouter simplement le package Introspect à votre projet.

Après cela, ajoutez import Introspect n'importe où dans vos fichiers de projet.

Ajoutez ensuite l'un de leurs modificateurs de vue à votre Textfield de Textfield pour obtenir ce que vous voulez. Je crois que c'est ce que vous voulez cependant ...

.introspectTextField { textfield in
  textfield.returnKeyType = .done
}

Que fait Introspect?

Il expose UIKit à utiliser dans Swift. Ainsi, l'objet Textfield que vous voyez ci-dessus a accès à toutes les fonctionnalités de UITextfield ! Il s'agit d'un package, alors sachez qu'il pourrait se rompre à l'avenir, mais pour l'instant, c'est une bonne option.

C'est juste bien car cela vous évite de créer votre propre wrapper UIKit pour chaque vue 😊


0 commentaires