IOS 15
Il existe un nouveau wrapper appelé @FocusState
qui contrôle l'état du clavier et du clavier ciblé ('aka' firstResponder).
Devenir premier répondant (ciblé)
Si vous utilisez un focused
sur les champs de texte, vous pouvez les mettre en évidence :
Démissionner du poste de premier intervenant ( Renvoyer le clavier )
ou annuler le clavier en mettant la variable à nil
:
iOS 13 et supérieur : Vieux mais fonctionnel !
Structure wrapper simple - fonctionne comme une structure native :
<strong>Notez que </strong>Le support de la reliure de texte a été ajouté comme demandé dans les commentaires
struct LegacyTextField: UIViewRepresentable {
@Binding public var isFirstResponder: Bool
@Binding public var text: String
public var configuration = { (view: UITextField) in }
public init(text: Binding<String>, isFirstResponder: Binding<Bool>, configuration: @escaping (UITextField) -> () = { _ in }) {
self.configuration = configuration
self._text = text
self._isFirstResponder = isFirstResponder
}
public func makeUIView(context: Context) -> UITextField {
let view = UITextField()
view.addTarget(context.coordinator, action: #selector(Coordinator.textViewDidChange), for: .editingChanged)
view.delegate = context.coordinator
return view
}
public func updateUIView(_ uiView: UITextField, context: Context) {
uiView.text = text
configuration(uiView)
switch isFirstResponder {
case true: uiView.becomeFirstResponder()
case false: uiView.resignFirstResponder()
}
}
public func makeCoordinator() -> Coordinator {
Coordinator($text, isFirstResponder: $isFirstResponder)
}
public class Coordinator: NSObject, UITextFieldDelegate {
var text: Binding<String>
var isFirstResponder: Binding<Bool>
init(_ text: Binding<String>, isFirstResponder: Binding<Bool>) {
self.text = text
self.isFirstResponder = isFirstResponder
}
@objc public func textViewDidChange(_ textField: UITextField) {
self.text.wrappedValue = textField.text ?? ""
}
public func textFieldDidBeginEditing(_ textField: UITextField) {
self.isFirstResponder.wrappedValue = true
}
public func textFieldDidEndEditing(_ textField: UITextField) {
self.isFirstResponder.wrappedValue = false
}
}
}
Utilisation :
struct ContentView: View {
@State var text = ""
@State var isFirstResponder = false
var body: some View {
LegacyTextField(text: $text, isFirstResponder: $isFirstResponder)
}
}
Bonus : Entièrement personnalisable
LegacyTextField(text: $text, isFirstResponder: $isFirstResponder) {
$0.textColor = .red
$0.tintColor = .blue
}
Cette méthode est entièrement adaptable. Par exemple, vous pouvez voir Comment ajouter un indicateur d'activité dans SwiftUI avec la même méthode aquí
14 votes
Le fait que quelque chose de basique comme cela ne soit même pas supporté montre à quel point SwiftUI est immature pour le moment. Regardez les solutions ci-dessous, c'est ridicule pour quelque chose qui est censé rendre le codage de l'interface graphique "plus simple".