Je fais une application qui utilise un UITextView
. Maintenant, je veux que la vue texte ait un espace réservé similaire à celui que vous pouvez définir pour un champ de texte. Comment pourriez-vous accomplir cela en utilisant Swift?
ios
swift
uitextview
placeholder
StevenR
la source
la source
Réponses:
Mis à jour pour Swift 4
UITextView
n'a pas intrinsèquement de propriété d'espace réservé, vous devez donc en créer et en manipuler une par programmation à l'aide deUITextViewDelegate
méthodes. Je recommande d'utiliser la solution # 1 ou # 2 ci-dessous en fonction du comportement souhaité.Remarque: pour l'une ou l'autre solution, ajoutez
UITextViewDelegate
à la classe et définisseztextView.delegate = self
pour utiliser les méthodes déléguées de la vue texte.Solution n ° 1 - Si vous souhaitez que l'espace réservé disparaisse dès que l'utilisateur sélectionne la vue texte:
Définissez d'abord le
UITextView
pour contenir le texte d'espace réservé et définissez-le sur une couleur gris clair pour imiter l'apparence duUITextField
texte d'espace réservé d'un. Faites-le dans laviewDidLoad
ou lors de la création de la vue texte.Ensuite, lorsque l'utilisateur commence à modifier la vue texte, si la vue texte contient un espace réservé (c'est-à-dire si sa couleur de texte est gris clair), effacez le texte d'espace réservé et définissez la couleur du texte sur noir afin de s'adapter à l'entrée de l'utilisateur.
Ensuite, lorsque l'utilisateur a terminé de modifier la vue texte et qu'elle a démissionné en tant que premier répondant, si la vue texte est vide, réinitialisez son espace réservé en ajoutant à nouveau le texte d'espace réservé et en définissant sa couleur sur gris clair.
Solution n ° 2 - Si vous souhaitez que l'espace réservé s'affiche chaque fois que la vue texte est vide, même si la vue texte est sélectionnée:
Définissez d'abord l'espace réservé dans
viewDidLoad
:(Remarque: comme l'OP voulait que la vue texte soit sélectionnée dès que la vue se charge, j'ai incorporé la sélection de la vue texte dans le code ci-dessus. Si ce n'est pas le comportement souhaité et que vous ne voulez pas que la vue texte soit sélectionnée lors du chargement de la vue, supprimez les deux dernières lignes du bloc de code ci-dessus.)
Ensuite, utilisez la
shouldChangeTextInRange
UITextViewDelegate
méthode, comme ceci:Et également implémenter
textViewDidChangeSelection
pour empêcher l'utilisateur de changer la position du curseur alors que l'espace réservé est visible. (Remarque:textViewDidChangeSelection
est appelé avant le chargement de la vue, ne vérifiez la couleur de la vue texte que si la fenêtre est visible):la source
yourTextField.delegate = self
. Si vous ne le faites pas,textViewDidBeginEditing
lestextViewDidEndEditing
fonctions et ne fonctionneront pas.Cannot convert value of type 'NSRange' (aka '_NSRange') to expected argument type 'Range<String.Index>' (aka 'Range<String.CharacterView.Index>')
.let currentText = textView.text as NSString?
. Transformez lalet updatedText =
ligne enlet updatedText = currentText?.replacingCharacters(in: range, with: text)
. Enfin, transformez laif updatedText.isEmpty
ligne enif (updatedText?.isEmpty)! {
. Cela devrait faire l'affaire!textView.selectedTextRange
de l'intérieurfunc textViewDidChangeSelection(_ textView: UITextView)
provoque une boucle infinie ...Espace réservé flottant
Il est simple, sûr et fiable de positionner une étiquette d'espace réservé au-dessus d'une vue texte, de définir sa police, sa couleur et de gérer la visibilité des espaces réservés en suivant les modifications du nombre de caractères de la vue texte.
Swift 3:
Swift 2: Idem, sauf:
italicSystemFontOfSize(textView.font.pointSize)
,UIColor.lightGrayColor
la source
Je recommande fortement d'utiliser la bibliothèque KMPlaceholderTextView . Très simple à utiliser.
la source
Rapide:
Ajoutez votre vue texte par programme ou via Interface Builder, si le dernier, créez la sortie:
Veuillez ajouter le délégué (UITextViewDelegate):
Dans la méthode viewDidLoad, ajoutez les éléments suivants:
Maintenant, laissez-moi vous présenter la partie magique, ajoutez cette fonction:
Notez que cela s'exécutera chaque fois que l'édition commencera, nous vérifierons les conditions pour indiquer l'état, en utilisant la propriété color. Définition du texte sur
nil
je ne recommande pas. Juste après cela, nous avons défini la couleur du texte sur la couleur souhaitée, dans ce cas, le noir.Maintenant, ajoutez également cette fonction:
Permettez-moi d'insister, ne comparez pas à
nil
, j'ai déjà essayé cela et cela ne fonctionnerait pas. Nous redéfinissons ensuite les valeurs sur le style de l'espace réservé et redéfinissons la couleur sur la couleur de l'espace réservé car c'est une condition pour l'archivagetextViewDidBeginEditing
.la source
Utilisez cette extension, c'est la meilleure façon de définir un espace réservé dans UITextView. Mais assurez-vous d'avoir attaché des délégués à TextView. Vous pouvez définir un espace réservé comme ceci: -
la source
Je suis surpris que personne n'ait mentionné
NSTextStorageDelegate
.UITextViewDelegate
Les méthodes de ne seront déclenchées que par l'interaction de l'utilisateur, mais pas par programme. Par exemple, lorsque vous définissez une vue de textetext
propriété d' programme, vous devrez définir vous-même la visibilité de l'espace réservé, car les méthodes déléguées ne seront pas appelées.Cependant, avec
NSTextStorageDelegate
latextStorage(_:didProcessEditing:range:changeInLength:)
méthode de, vous serez averti de toute modification du texte, même si elle est effectuée par programme. Attribuez-le simplement comme ceci:(Dans
UITextView
, cette propriété déléguée estnil
par défaut, elle n'affectera donc aucun comportement par défaut.)Combiner avec la
UILabel
technique @clearlight montre, on peut facilement envelopper l'ensembleUITextView
de laplaceholder
mise en œuvre dans une extension.Notez que l'utilisation d'une classe privée (imbriquée) appelée
PlaceholderLabel
. Il n'a aucune implémentation du tout, mais il nous fournit un moyen d'identifier l'étiquette d'espace réservé, qui est beaucoup plus «swifty» que d'utiliser letag
propriété.Avec cette approche, vous pouvez toujours affecter le délégué de
UITextView
à quelqu'un d'autre.Vous n'avez même pas besoin de changer les classes de vos vues de texte. Ajoutez simplement les extensions et vous pourrez attribuer une chaîne d'espace réservé à chaque élément de
UITextView
votre projet, même dans Interface Builder.J'ai omis l'implémentation d'une
placeholderColor
propriété pour des raisons de clarté, mais elle peut être implémentée pour quelques lignes de plus avec une variable calculée similaire àplaceholder
.la source
textView.textStorage.delegate = self
cela dans un contrôleur de vue nous obligera à lier ce contrôleur de vue avecNSTextStorageDelegate
. C'est vraiment nécessaire?NSTextStorageDelegate
, pas le contrôleur de vue.Je l'ai fait en utilisant deux vues de texte différentes:
L'idée est qu'une fois que l'utilisateur commence à taper des éléments dans la vue de premier plan, l'espace réservé à l'arrière-plan disparaît (et réapparaît si l'utilisateur supprime tout). Il se comporte donc exactement comme un espace réservé pour le champ de texte sur une seule ligne.
Voici le code que j'ai utilisé pour cela. Notez que descriptionField est le champ dans lequel l'utilisateur tape et descriptionPlaceholder est celui en arrière-plan.
la source
Sur la base de certaines des excellentes suggestions ici déjà, j'ai pu rassembler la sous-classe légère et compatible avec Interface-Builder suivante
UITextView
, qui:UITextField
.text
propriété du champ .Toutes les suggestions d'amélioration sont les bienvenues, surtout s'il existe un moyen de tirer la couleur de l'espace réservé d'iOS par programme, plutôt que de la coder en dur.
Swift v5:
la source
SET value in view load
la source
J'ai essayé de rendre le code pratique de clearlight de réponse .
usage
la source
Une autre solution (Swift 3):
résultat
la source
Une solution simple et rapide qui fonctionne pour moi est:
la source
Voici ce que j'utilise pour ce travail.
Je sais qu'il existe plusieurs approches similaires à celle-ci, mais les avantages de celle-ci sont:
la source
Swift 3.2
Tout d'abord, lorsque l'utilisateur commence à modifier l'appel textViewDidBeginEditing, puis vérifiez si la couleur du texte gris signifie que l'utilisateur n'a rien écrit, définissez-la comme textview nil et changez la couleur en noir pour les SMS de l'utilisateur.
Lorsque l'utilisateur termine l'édition textViewDidEndEditing est appel et vérifier si l'utilisateur n'écrit rien dans textview puis le texte défini en couleur grise avec le texte "PlaceHolder"
la source
Voici ma façon de résoudre ce problème ( Swift 4 ):
L'idée était de faire la solution la plus simple possible qui permet d'utiliser des espaces réservés de différentes couleurs, se redimensionne à la taille des espaces réservés, n'écrase pas en
delegate
attendant de garder toutes lesUITextView
fonctions fonctionnent comme prévu.la source
Je ne sais pas pourquoi les gens compliquent trop ce problème ... C'est assez simple et simple. Voici une sous-classe de UITextView qui fournit les fonctionnalités demandées.
la source
Ceci est ma solution prête à l'emploi si vous travaillez avec plusieurs vues de texte
la source
Swift 3.1
Cette extension a bien fonctionné pour moi: https://github.com/devxoul/UITextView-Placeholder
Voici un extrait de code:
Installez-le via pod:
Importez-le dans votre classe
Et ajoutez une
placeholder
propriété à votre déjà crééUITextView
C'est ça ... Voici à quoi ça ressemble (la troisième case est a
UITextView
)la source
Contrairement à peu près toutes les réponses à ce poste, n'ont une propriété de l' espace réservé. Pour des raisons au-delà de ma compréhension, il n'est exposé qu'en IB, en tant que tel:
UITextView
Donc, si vous utilisez des storyboards et qu'un espace réservé statique suffit, définissez simplement la propriété sur l'inspecteur.
Vous pouvez également définir cette propriété dans un code comme celui-ci:
Son nuageux quant à la météo est accessible via une API privée, car la propriété est exposée.
Je n'ai pas essayé de soumettre avec cette méthode. Mais je soumettrai cette façon sous peu et mettrai à jour cette réponse en conséquence.
METTRE À JOUR:
J'ai expédié ce code dans plusieurs versions sans problème d'Apple.
MISE À JOUR: Cela ne fonctionnera que dans Xcode pre 11.2
la source
UITextField
PASUITextView
s'il vous plaît lire les questions / réponses plus attentivement.Il n'y a pas une telle propriété dans ios pour ajouter un espace réservé directement dans TextView, vous pouvez plutôt ajouter une étiquette et afficher / masquer le changement dans textView. SWIFT 2.0 et assurez-vous d'implémenter le textviewdelegate
la source
Swift - J'ai écrit une classe qui a hérité d'UITextView et j'ai ajouté un UILabel en tant que sous-vue pour agir comme un espace réservé.
la source
J'aime la solution de @ nerdist. Sur cette base, j'ai créé une extension pour
UITextView
:Dans une classe ViewController, par exemple, voici comment je l'utilise:
Placeholder sur UITextview!
MISE À JOUR :
Si vous modifiez le texte de textview dans le code, n'oubliez pas d'appeler la méthode updateVisibitly pour masquer l'espace réservé:
Pour empêcher l'ajout d'espace réservé plus d'une fois, une
add()
fonction privée est ajoutéeextension
.la source
Dans swift2.2:
}
Dans swift3:
classe CustomTextView: UITextView {
}
J'ai écrit un cours en swift. Vous devez importer cette classe chaque fois que nécessaire.
la source
Je ne peux pas ajouter de commentaire à cause de la réputation. ajouter un besoin de délégué supplémentaire dans la réponse @clearlight.
est besoin
parce
textViewDidChange
qu'on ne l'appelle pas la première foisla source
non, aucun espace réservé n'est disponible pour l'affichage de texte. vous devez mettre une étiquette au-dessus lorsque l'utilisateur entre dans textview, puis la masquer ou la définir par défaut lorsque l'utilisateur entre supprimer toutes les valeurs.
la source
la source
J'ai dû répartir la file d'attente pour que mon texte d'espace réservé réapparaisse une fois l'édition terminée.
la source
Rapide:
Ajoutez votre
TextView
@IBOutlet
:Dans la
viewWillAppear
méthode, ajoutez les éléments suivants:Veuillez ajouter l'
Delegate
extension Using (UITextViewDelegate):la source
Notre solution évite de nettoyer les propriétés
UITextView
text
ettextColor
, ce qui est pratique si vous maintenez un compteur de caractères.C'est simple:
1) Créez un mannequin
UITextView
dans Storyboard avec les mêmes propriétés que le maîtreUITextView
. Attribuez un texte d'espace réservé au texte factice.2) Alignez les bords supérieur, gauche et droit des deux
UITextViews.
3) Placez le mannequin derrière le maître.
4) Remplacez la
textViewDidChange(textView:)
fonction de délégué du maître et montrez le mannequin si le maître a 0 caractères. Sinon, montrez le maître.Cela suppose que les deux
UITextViews
ont des arrière-plans transparents. Si ce n'est pas le cas, placez le mannequin sur le dessus quand il y a 0 caractères et poussez-le en dessous quand il y a> 0 caractères. Vous devrez également permuter les répondeurs pour vous assurer que le curseur suit la droiteUITextView
.la source
Swift 4, 4.2 et 5
la source