Lorsque vous utilisez le nouveau TextEditor de SwiftUI, vous pouvez modifier son contenu directement à l'aide d'un @State. Cependant, je ne vois pas de moyen d'y ajouter un texte d'espace réservé. Est-ce faisable maintenant?
J'ai ajouté un exemple qu'Apple a utilisé dans sa propre application de traduction. Ce qui semble être une vue d'éditeur de texte à plusieurs lignes prenant en charge un texte d'espace réservé.
5 Réponses :
Ce n'est pas possible dès le départ, mais vous pouvez obtenir cet effet avec ZStack ou la propriété .overla y.
Ce que vous devez faire est de vérifier la propriété détenant votre état. S'il est vide, affichez votre texte d'espace réservé. Si ce n'est pas le cas, affichez plutôt le texte saisi.
Et voici un exemple de code:
TextEditor(text: stringProperty) .opacity(stringProperty.isEmpty ? 0.25 : 1)
Remarque: J'ai volontairement laissé le style .font et .padding pour que vous voyiez qu'il devrait correspondre à la fois sur TextEditor et sur Text.
EDIT: En gardant à l'esprit les deux problèmes mentionnés dans le commentaire de Legolas Wang, voici comment les problèmes d'alignement et d'opacité pourraient être traités:
HStack { Text("Some placeholder text") Spacer() }
ZStack(alignment: .leading) { if email.isEmpty { Text(Translation.email) .font(.custom("Helvetica", size: 24)) .padding(.all) } TextEditor(text: $email) .font(.custom("Helvetica", size: 24)) .padding(.all) }
Bien sûr, cette solution n'est qu'une solution de contournement stupide jusqu'à ce que le support soit ajouté pour TextEditors.
C'est une pensée brillante, mais malheureusement elle a souffert de deux problèmes. Le premier est la vue TextEditor, qui est opaque, elle bloquera donc la vue d'espace réservé lors de la superposition par-dessus dans un ZStack. Ajuster avec l'opacité pourrait aider un peu dans ce cas. Le deuxième problème est la logique du cadre avec Text et TextEditor, TextEditor commence à partir du coin supérieur gauche et le texte commence à partir du centre de la vue. Ce qui les rend très difficiles à superposer exactement sur le dessus. Avez-vous des réflexions sur le problème d'alignement?
@LegolasWang Je ne voulais rien inclure de très spécifique sur le style, mais j'ai laissé la police et le remplissage uniquement pour démontrer que le style, l'alignement, etc. doivent correspondre. J'ajoute une modification à ma réponse pour montrer comment ces 2 problèmes mentionnés ci-dessus pourraient être traités.
Vous pouvez en fait placer le HStack
sous TextEditor
et lui donner un .contentShape
de NoShape
: `` `` struct NoShape: Shape {func path (in rect: CGRect) -> Path {return Path ()}} // ... HStack {Text ("Some placeholder text") .contentShape (NoShape ())} `` `
Jusqu'à ce que nous ayons un support API, une option serait d'utiliser la chaîne de liaison comme espace réservé et onTapGesture pour la supprimer
TextEditor(text: self.$note) .padding(.top, 20) .foregroundColor(self.note == placeholderString ? .gray : .primary) .onTapGesture { if self.note == placeholderString { self.note = "" } }
J'ai créé une vue personnalisée qui peut être utilisée comme celle-ci (jusqu'à ce que TextEditor le prenne officiellement en charge - peut-être l'année prochaine)
struct TextArea: View { private let placeholder: String @Binding var text: String init(_ placeholder: String, text: Binding<String>) { self.placeholder = placeholder self._text = text } var body: some View { TextEditor(text: $text) .background( HStack(alignment: .top) { text.isBlank ? Text(placeholder) : Text("") Spacer() } .foregroundColor(Color.primary.opacity(0.25)) .padding(EdgeInsets(top: 0, leading: 4, bottom: 7, trailing: 0)) ) } } extension String { var isBlank: Bool { return allSatisfy({ $0.isWhitespace }) } }
Solution complète ci-dessous:
TextArea("This is my placeholder", text: $text)
J'utilise le remplissage par défaut de TextEditor ici, mais n'hésitez pas à vous adapter à vos préférences.
en quelque sorte, il y a un avion blanc superposant l'espace réservé 🤔
Je l'utilise toujours sur iOS 14.2 (mode clair et sombre) et aucun problème jusqu'à présent. Si vous l'utilisez avec d'autres vues personnalisées, vous voudrez peut-être modifier un peu le code en fonction de vos besoins. N'hésitez pas à partager votre capture d'écran et votre code 😊
Le jour où vous pouvez utiliser un TextEditor pour supprimer le clavier, semblable à un TextField, est le jour où je me réjouis.
Comme je le sais, c'est la meilleure façon d'ajouter un texte d'espace réservé à TextEditor dans SwiftUI
struct ContentView: View { @State var text = "Type here" var body: some View { TextEditor(text: self.$text) // make the color of the placeholder gray .foregroundColor(self.text == "Type here" ? .gray : .primary) .onAppear { // remove the placeholder text when keyboard appears NotificationCenter.default.addObserver(forName: UIResponder.keyboardWillShowNotification, object: nil, queue: .main) { (noti) in withAnimation { if self.text == "Type here" { self.text = "" } } } // put back the placeholder text if the user dismisses the keyboard without adding any text NotificationCenter.default.addObserver(forName: UIResponder.keyboardWillHideNotification, object: nil, queue: .main) { (noti) in withAnimation { if self.text == "" { self.text = "Type here" } } } } } }
Il y a de bonnes réponses ici, mais je voulais évoquer un cas particulier. Lorsqu'un TextEditor est placé dans un formulaire, il y a quelques problèmes, principalement avec l'espacement.
Une façon de résoudre ces problèmes:
Form { TextField("Text Field", text: $text) ZStack(alignment: .topLeading) { if comments.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty { Text("Long Text Field").foregroundColor(Color(UIColor.placeholderText)).padding(.top, 8) } TextEditor(text: $comments).padding(.leading, -3) } }
Je ne pense pas que ce soit possible maintenant. C'est toujours la version bêta, donc cela pourrait changer.
Je crois à peine que ce sera jamais, c'est TextEditor, pas TextField. Il n'y avait pas non plus d'espace réservé dans UITextView.
@Asperi J'ai ajouté un exemple de l'application de traduction d'Apple, qui semble avoir une vue TextEditor qui prend en charge l'espace réservé. J'essaye de réaliser la même chose.
Le mot clé est semble ... regarde cette solution Comment créer un TextField multiligne dans SwiftUI?
J'ai créé un assistant de rétroaction demandant que cela soit disponible dans la version finale de Xcode 12 🙏 (FB8118309)