Affichage De Texte (UITextView) Espace Réservé Swift
Je suis en train de faire une application qui utilise un UITextView
. Maintenant, je veux le Texte afin de disposer d'un espace réservé semblable à celui que vous pouvez définir pour un Champ de Texte. Comment voulez-vous accomplir cela en utilisant swift.
Personne ne sait comment faire cela?
- C'est un vieux problème dans le développement d'iOS avec UITextView. J'ai écrit les sous-classes comme celle mentionnée ici: stackoverflow.com/a/1704469/1403046 . L'avantage est que vous pouvez toujours avoir un délégué, ainsi que l'utilisation de la classe en plusieurs endroits sans avoir à re-mettre en œuvre la logique.
- Comment puis-je utiliser votre sous-classe, tandis que l'utilisation de swift pour le projet. À l'aide d'un pont de fichier?
- Vous pourriez le faire, ou ré-implémenter dans Swift. Le code de la réponse est plus longue que il a vraiment l'être. L'essentiel étant d'afficher/masquer l'étiquette que vous ajoutez dans la méthode, vous êtes averti lorsque la modification du texte.
- Vous pouvez utiliser UIFloatLabelTextView de l'échantillon à partir de GitHub. Cette position de l'espace réservé sur le dessus lors de l'écriture. Vraiment intéressant! github.com/ArtSabintsev/UIFloatLabelTextView
- Honnêtement, la meilleure façon de le faire est d'avoir un custom textView et juste ajouter un espace réservé de texte qui est dessiné sur le textView lorsque le texte est présent.... Jamais de réponse à ce jour a été une bien trop compliqué version de ce qu'implique la problématique de la gestion de l'état (y compris les faux positifs lorsque le texte devrait/ne devrait pas ne/n'existe pas)
- il a été créé pour répondre à cette préoccupation: stackoverflow.com/a/28271069/2079103
- c'est encore plus compliqué que ma solution lol. C'est également le basculement de vue différents, les états et les différents types de classes (un UILabel et un UITextView).
- Aimerais voir un exemple.
- c'est l'une des réponses ci-dessous lol: stackoverflow.com/questions/27652227/...
UITextView
a un espace réservé à la propriété, vous avez juste à définir au sein de l'IB ou via le chemin d'accès clé. Pas besoin de sous-classement, à moins que la logique supplémentaire doit être appliquée à l'état. stackoverflow.com/questions/27652227/...
Vous devez vous connecter pour publier un commentaire.
Mis à jour pour Swift 4
UITextView
n'est pas forcément à avoir un espace réservé à la propriété, de sorte que vous auriez à créer et manipuler un par programmation à l'aideUITextViewDelegate
méthodes. Je recommande d'utiliser l'une ou l'autre solution #1 ou #2 ci-dessous, selon le comportement souhaité.Remarque: Pour l'une ou l'autre solution, ajouter
UITextViewDelegate
de la classe et de l'ensembletextView.delegate = self
d'utiliser le texte de la vue du délégué méthodes.Solution #1 - Si vous voulez de l'espace réservé à disparaître dès que l'utilisateur sélectionne l'affichage de texte:
D'abord définir la
UITextView
pour contenir le texte de l'espace réservé et réglé pour un peu de couleur grise pour imiter l'aspect d'unUITextField
s'du texte d'espace réservé. Soit le faire dans leviewDidLoad
ou lors de l'affichage du texte de la création.Ensuite, lorsque l'utilisateur commence à modifier l'affichage de texte, si l'affichage de texte contient un espace réservé (c'est à dire si sa couleur de texte est en gris clair) effacer le texte de l'espace réservé et définir la couleur du texte noir afin de permettre l'entrée d'utilisateur.
Ensuite, lorsque l'utilisateur a terminé l'édition de l'affichage de texte et il a démissionné de son poste le premier intervenant, si l'affichage de texte est vide, la réinitialisation de l'espace réservé par le nouvel ajout de l'espace réservé de texte et définition de sa couleur gris clair.
Solution #2 - Si vous voulez de l'espace réservé pour montrer à chaque fois que l'affichage de texte est vide, même si l'affichage de texte sélectionné:
Tout d'abord définir l'espace réservé dans la
viewDidLoad
:(Note: Depuis l'OP voulait avoir l'affichage de texte sélectionné dès que le point de vue des charges, j'ai incorporé le texte de sélection de la vue dans le code ci-dessus. Si ce n'est pas votre comportement désiré et vous ne voulez pas que l'affichage de texte sélectionnée lors de la vue de la charge, de supprimer les deux dernières lignes du code ci-dessus morceau.)
Ensuite utiliser la
shouldChangeTextInRange
UITextViewDelegate
méthode, comme suit:Et également de mettre en œuvre
textViewDidChangeSelection
pour empêcher l'utilisateur de modifier la position du curseur, tandis que l'espace réservé du visible. (Note:textViewDidChangeSelection
est appelé avant le point de vue de charges pour seulement vérifier l'affichage de texte de couleur si la fenêtre est visible):if countElements(text) == 0
- qui semble également fonctionner. En regardant le "shouldChangeTextInRange" la méthode, il semble que le "texte" paramètre pour le remplacement d'un nouveau texte, donc il semble que vous pourriez tester si la valeur du texte est 0 ou pas, au lieu de la updatedText variable. Est-il une question qui me manque avec cette idée?if countElements(text) == 0
. C'est pourquoi vous pour de le faire en utilisant une sorte deupdatedText
variable de combiner l'ancien texte par le texte de remplacement afin d'être en mesure de détecter correction arrière de façon appropriée.countElements
est utilisé deux fois dans votre code, cela a été modifié dans une version plus récente de swift à justecount
.nil
ne fonctionne pas pour moi, au lieu de faire une comparaison de""
, l'absence de texte.if self.view.window != nil
je ne vois pas de néant comparaisons dans le code que j'ai écrit... au Lieu de comparer le texte avec "", j'ai utilisé leisEmpty
propriété:if textView.text.isEmpty {
. Je vous recommande d'utiliserisEmpty
plus de faire une comparaison de "".UITextView
's n'ont pas un espace réservé à la propriété, d'où la nécessité pour cette solution de contournement.yourTextField.delegate = self
. Si vous ne le faites pas, letextViewDidBeginEditing
et latextViewDidEndEditing
fonctions ne fonctionneront pas.Cannot convert value of type 'NSRange' (aka '_NSRange') to expected argument type 'Range<String.Index>' (aka 'Range<String.CharacterView.Index>')
.let updatedText = currentText?.replacingCharacters(in: Range(range, in: currentText!)!, with: text)
let updatedText =
ligne.let currentText = textView.text as NSString?
. Transformer lelet updatedText =
lignelet updatedText = currentText?.replacingCharacters(in: range, with: text)
. Enfin, transformer leif updatedText.isEmpty
ligneif (updatedText?.isEmpty)! {
. Que devrait faire l'affaire!textView.selectedTextRange
de l'intérieurfunc textViewDidChangeSelection(_ textView: UITextView)
provoque une boucle infinie...UITextView
t ont unplaceholder
de la propriété. Il peut être mis dans de l'IB ou via le chemin d'accès cléUITextView
? @LyndseyScottFlottant Espace Réservé
C'est simple, sûr et fiable pour la position d'un espace réservé à l'étiquette au-dessus d'un affichage de texte, définissez sa police, de la couleur et de gérer l'espace réservé de la visibilité par le suivi des modifications apportées au texte de la vue du nombre de caractères.
Swift 3:
Swift 2: Même, à l'exception de:
italicSystemFontOfSize(textView.font.pointSize)
,UIColor.lightGrayColor
UITableViewAutomaticDimension
,beginUpdates()
,endUpdates()
. Lorsque le texte est vide et l'espace réservé est visible (une seule ligne), je veux qu'il ressemble et se comporte plus comme un centre alignéUITextField
, qui j'en suis sûr, place le curseur à gauche d'une centrée sur l'espace réservé.Recommandons fortement d'utiliser le KMPlaceholderTextView de la bibliothèque. Très simple à utiliser.
Swift:
Ajouter votre texte à afficher par programme ou par l'intermédiaire de l'Interface Builder, si le dernier, de créer de la sortie:
S'il vous plaît ajouter le délégué (UITextViewDelegate):
Dans la méthode viewDidLoad, ajoutez la suivante:
Maintenant, permettez-moi de vous présenter de la part de magie, d'ajouter cette fonction:
Ne remarque que cela permettra d'exécuter à chaque fois que l'édition démarre, il nous permettra de vérifier les conditions à dire l'état, à l'aide de la couleur à la propriété.
La mise en texte de
nil
je ne le recommande pas. Juste après cela, nous avons défini la couleur du texte souhaité, dans ce cas, les noirs.Maintenant ajouter cette fonction trop:
Permettez-moi d'insister, ne pas se comparer à
nil
, j'ai déjà essayé et cela ne fonctionne pas. Nous avons ensuite défini les valeurs de retour à l'espace réservé de style, et de définir la couleur d'arrière à l'espace réservé de la couleur parce que c'est une condition pour vérifier danstextViewDidBeginEditing
.Utiliser Cette Extension c'est la meilleure façon de définir l'espace réservé dans UITextView.
Mais assurez-vous que vous avez branché les délégués à la TextView. Vous pouvez définir la Place de titulaire comme ceci:-
Je l'ai fait à l'aide de deux de texte différents points de vue:
L'idée est qu'une fois que l'utilisateur commence à taper des trucs dans le premier plan de la vue, l'espace réservé à l'arrière-plan disparaît (et réapparaît lorsque l'utilisateur supprime tout). De sorte qu'il se comporte exactement comme un espace réservé pour la seule ligne de champ de texte.
Voici le code que j'ai utilisé pour cela. Notez que descriptionField est le champ de l'utilisateur tape dans et descriptionPlaceholder est l'un dans le fond.
Je suis surpris que personne n'ait mentionné
NSTextStorageDelegate
.UITextViewDelegate
's méthodes ne sera déclenchée que par l'interaction de l'utilisateur, mais pas par programme. E. g. lorsque vous définissez un texte en vue de l'text
propriété de la programmation, vous devrez définir l'espace réservé à la visibilité de vous-même, parce que le délégué méthodes ne sera pas appelé.Cependant, avec
NSTextStorageDelegate
'stextStorage(_:didProcessEditing:range:changeInLength:)
méthode, vous serez informé de tout changement dans le texte, même si c'est fait par programmation. Juste de l'attribuer comme ceci:(En
UITextView
, ce délégué de la propriété estnil
par défaut, afin de ne pas affecter n'importe quel comportement par défaut.)De le combiner avec le
UILabel
technique @clearlight montre, on peut facilement enrouler l'ensemble de laUITextView
'splaceholder
la mise en œuvre dans une extension.De noter que l'utilisation d'un privé (imbriqué) classe appelée
PlaceholderLabel
. Il n'a pas de mise en œuvre à tous, mais il nous offre un moyen d'identifier l'espace réservé à l'étiquette, qui est bien plus "swifty" qu'à l'aide de latag
de la propriété.Avec cette approche, vous pouvez toujours affecter le délégué de la
UITextView
à quelqu'un d'autre.Vous n'avez même pas à modifier le texte des classes. Juste ajouter l'extension(s) et vous serez en mesure d'assigner une chaîne d'espace réservé à chaque
UITextView
dans votre projet, même dans Interface Builder.J'ai laissé de côté la mise en œuvre d'un
placeholderColor
propriété pour des raisons de clarté, mais il peut être mis en œuvre pour juste un peu plus de lignes avec une même variable calculé àplaceholder
.textView.textStorage.delegate = self
ce dans une vue-contrôleur va nous obliger à lier ce point de vue-contrôleur avecNSTextStorageDelegate
. Il est vraiment besoin?NSTextStorageDelegate
, pas le point de vue du contrôleur.Basé sur certains des plus grands suggestions ici déjà, j'ai été en mesure de mettre ensemble les suivantes léger, Interface Builder-compatible sous-classe de
UITextView
, dont:UITextField
.text
propriété.Toutes les suggestions d'amélioration sont les bienvenus, surtout si il y a moyen de tirer iOS espace réservé couleur par programmation, plutôt que de coder en dur elle.
Swift v5:
Valeur de réglage en vue de charge
La solution (Swift 3):
résultat
Une solution simple et rapide qui fonctionne pour moi est:
Voici ce que j'utilise pour ce travail.
Je sais il y en a plusieurs à des approches semblables à cela, mais les avantages de celui-ci sont:
J'ai essayé de faire le code de pratique de clearlight's réponse.
utilisation
Swift 3.2
Premier lorsque l'utilisateur de commencer le montage textViewDidBeginEditing appel, puis vérifier si la couleur du texte gris signifie que l'utilisateur n'ai pas à écrire quoi que ce soit alors définie comme textview néant et le changement de la couleur au noir pour l'utilisateur en langage sms.
Lorsque l'utilisateur a la fin de l'édition textViewDidEndEditing est de les appeler et vérifier si l'utilisateur ne rien écrire dans textview ensuite un texte en gris de la couleur avec le texte "espace Réservé"
Ici, c'est ma façon de résoudre ce problème (Swift 4):
L'idée était de faire le plus simple possible solution qui permet d'utiliser des espaces réservés de différentes couleurs, redimensionne à la taille des espaces réservés, n'écrasera pas un
delegate
en attendant la tenue de tousUITextView
fonctions de fonctionner comme prévu.Contraire à juste au sujet de chaque réponse sur ce post,
UITextView
ne ont un espace réservé à la propriété. Pour des raisons au-delà de ma compréhension, il n'est exposé à de l'IB, en tant que tel:Donc, si vous utilisez des story-boards et statique de l'espace réservé suffira, il suffit de définir la propriété sur l'inspecteur.
Vous pouvez également définir cette propriété dans le code comme ceci:
Son nuageux à temps, ce service est accessible via une API privée, comme la propriété est exposés.
Je n'ai pas essayé la soumission avec cette méthode. Mais je vais être la soumission de cette façon, peu de temps et se met à jour cette réponse en conséquence.
Mise à JOUR:
J'ai expédié ce code en plusieurs versions avec pas de questions de la part d'Apple.
Mise à JOUR:
Cela ne fonctionnera que dans Xcode pré 11.2
UITextField
PASUITextView
veuillez lire les questions/réponses avec plus de soin.*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<UITextView 0x7faeca8c4e00> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key placeholder.'
Je ne sais pas pourquoi les personnes de plus de compliquer ce problème tellement.... C'est assez simple et simple. Voici une sous-classe de UITextView qui fournit la fonctionnalité requise.
C'est mon prêt à utiliser la solution si vous travaillez avec du texte multiples points de vue
Swift 3.1
Cette extension a bien fonctionné pour moi: https://github.com/devxoul/UITextView-Placeholder
Voici un extrait de code:
L'installer via pod:
Les importer dans votre classe
Et ajouter
placeholder
propriété déjà crééUITextView
Thats it...
Voici à quoi il ressemble (Troisième case est un
UITextView
)Il n'y a pas de tels biens en ios pour ajouter un espace réservé directement dans le TextView plutôt que vous pouvez ajouter une étiquette et afficher/masquer sur le changement dans les textView. SWIFT 2.0 et assurez-vous de mettre en œuvre les textviewdelegate
Swift - j'ai écrit une classe qui a hérité de UITextView et j'ai ajouté un UILabel comme une sous-vue d'agir comme un espace réservé.
J'aime @nerdist de la solution. Sur cette base, j'ai créé une extension pour
UITextView
:Dans un ViewController classe, par exemple, c'est comment je l'utilise:
Espace réservé sur UITextview!
Mise à JOUR:
En cas de changement d'textview du texte dans le code, n'oubliez pas d'appeler updateVisibitly méthode pour masquer espace réservé:
Pour empêcher l'espace réservé ajouté plus d'une fois, d'une salle de
add()
fonction est ajoutée dansextension
.Dans swift2.2:
}
Dans swift3:
classe CustomTextView: UITextView {
}
J'ai écrit une classe en swift. Vous avez besoin d'importer cette classe chaque fois que nécessaire.
Je ne peux pas ajouter de commentaires en raison de la réputation. ajouter un délégué besoin dans @clearlight réponse.
est besoin
parce que
textViewDidChange
n'est pas appelée première foisnon, il n'est pas tout espace réservé disponibles pour textview. vous devez mettre de l'étiquette dessus lorsque l'utilisateur d'entrer dans textview alors de le cacher ou mettre en valeur par défaut lorsque l'utilisateur entre dans supprimer toutes les valeurs.
HTML:
J'ai eu à l'expédition de la file d'attente pour obtenir mon texte d'espace réservé pour réapparaître une fois que le montage est terminé.
Notre solution évite de coucher avec le
UITextView
text
ettextColor
propriétés, ce qui est pratique si vous êtes le maintien d'un compteur de caractères.C'est simple:
1) Créer un mannequin
UITextView
dans la table de montage avec les mêmes propriétés que le maîtreUITextView
. Attribuer texte de l'espace réservé pour le mannequin de texte.2) Alignez le haut, à gauche et à droite des deux
UITextViews.
3) Placer le mannequin derrière le maître.
4) Remplacer les
textViewDidChange(textView:)
fonction de délégué du maître, et de montrer le mannequin si le maître a 0 caractères. Sinon, montrer au maître.Cela suppose que les deux
UITextViews
des arrière-plans transparents. S'ils ne le font pas, placez le mannequin sur le dessus quand il y a des caractères 0, et le pousser en dessous quand il y a > 0 caractères. Vous aurez également pour échanger des intervenants assurez-vous que le curseur suit le droitUITextView
.Réponse Rapide
Ici est la classe personnalisée, qui anime un espace réservé.
Version de protocole clearlight's réponse ci-dessus, parce que les protocoles sont grands. Pop, où jamais vous s'il vous plaît. Dunk!
L'AFFICHAGE DU TEXTE DE DÉLÉGUÉ MÉTHODES
L'utilisation de ces deux délégué méthodes et aussi écrire UITextViewDelegate dans votre classe
Ici est quelque chose qui peut être déposé dans un
UIStackView
, il sera de taille à l'aide d'une hauteur intérieure de contrainte. Tweaking peut être nécessaire pour répondre à des besoins spécifiques.Swift:
Ajouter votre
TextView
@IBOutlet
:Dans le
viewWillAppear
méthode, n'ajoutez ce qui suit :S'il vous plaît ajouter le
Delegate
à l'Aide de l'extension (UITextViewDelegate):Une autre solution pourrait être d'utiliser keyboardWillHide et keyboardWillShow notifications, comme je l'ai fait.
D'abord vous avez besoin pour gérer l'écoute, et unlistening aux notifications dans la
viewWillAppear
etviewWillAppear
méthodes respectivement (pour traiter les fuites de mémoire).Ensuite la méthode pour gérer l'écoute/unlistening pour les notifications:
Puis dans les deux méthodes pour keyboardWillHide et keyboardWillShow vous gérer l'espace réservé et les changements de couleur du texte.
J'ai trouvé cette solution pour être le meilleur jusqu'à présent, puisque le texte sera supprimé dès que le clavier s'affiche à la place de lorsque l'utilisateur commence à taper, ce qui peut causer de la confusion.
Swift 4, 4.2 et 5
Je sais que c'est une vieille question, mais je voulais partager ce que je pensais être un moyen utile d'étendre UITextView avoir placeholderText et placeholderColor champs. Fondamentalement, vous lancez la UITextView dans un UITextField et puis définissez la attributedPlaceholder champ. PlaceholderText et placeholderColor sont IBInspectable champs, de sorte que leurs valeurs peuvent être définies dans l'IB et se comporte exactement comme la UITextField la fonctionnalité d'espace réservé.
UITextView+Étendre.h
UITextView+Étendre.m