J'ai un UILabel
endroit où je veux ajouter de l'espace en haut et en bas. Avec une hauteur minimale dans contrainte, je l'ai modifié pour:
EDIT: Pour ce faire, j'ai utilisé:
override func drawTextInRect(rect: CGRect) {
var insets: UIEdgeInsets = UIEdgeInsets(top: 0.0, left: 10.0, bottom: 0.0, right: 10.0)
super.drawTextInRect(UIEdgeInsetsInsetRect(rect, insets))
}
Mais je dois trouver une méthode différente car si j'écris plus de deux lignes, le problème est le même:
Réponses:
Si vous souhaitez vous en tenir à UILabel, sans le sous-classer, Mundi vous a donné une solution claire.
Si vous souhaitez également éviter d'encapsuler l'UILabel avec un UIView, vous pouvez utiliser UITextView pour activer l'utilisation de UIEdgeInsets (remplissage) ou de la sous-classe UILabel pour prendre en charge UIEdgeInsets.
L'utilisation d'un UITextView aurait seulement besoin de fournir les inserts (OBJ-C):
Alternative, si vous sous- classez UILabel , un exemple de cette approche remplacerait la méthode drawTextInRect
(OBJ-C)
Vous pouvez en outre fournir à votre nouveau UILabel sous-classé avec des variables d'encart pour TOP, LEFT, BOTTOM et RIGHT.
Un exemple de code pourrait être:
Dans .h (OBJ-C)
En .m (OBJ-C)
EDIT # 1:
D'après ce que j'ai vu, il semble que vous deviez remplacer intrinsicContentSize du UILabel lors du sous-classement.
Vous devez donc remplacer intrinsicContentSize comme:
Et ajoutez la méthode suivante pour modifier vos inserts, au lieu de les modifier individuellement:
Il mettra à jour la taille de votre UILabel pour correspondre aux inserts de bord et couvrir la nécessité multiligne dont vous avez parlé.
Modifier # 2
Après avoir cherché un peu, j'ai trouvé ce Gist avec un IPInsetLabel. Si aucune de ces solutions ne fonctionne, vous pouvez l'essayer.
Modifier # 3
Il y avait une question similaire (duplicata) à ce sujet.
Pour une liste complète des solutions disponibles, consultez cette réponse: marge de texte UILabel
la source
J'ai essayé avec Swift 4.2 , j'espère que cela fonctionnera pour vous!
Ou vous pouvez utiliser CocoaPods ici https://github.com/levantAJ/PaddingLabel
pod 'PaddingLabel', '1.2'
la source
min
Swift 3
la source
Vous pouvez le faire correctement depuis IB:
la source
SWIFT 4
Solution facile à utiliser, disponible pour tous les enfants UILabel du projet.
Exemple:
Extension UILabel
la source
Utilisez simplement a
UIView
comme vue de supervision et définissez une marge fixe sur l'étiquette avec mise en page automatique.la source
drawTextInRect
ne fonctionne que pour 1 ligne,intrinsicContentSize
ne fonctionne pas avec un remplissage horizontal. Envelopper UILabel dans UIView est la bonne façon d'allerUtilisez simplement un UIButton, il est déjà intégré. Désactivez toutes les fonctionnalités supplémentaires des boutons et vous obtenez une étiquette sur laquelle vous pouvez définir des instets de bord.
la source
isUserInteractionEnabled = false
est pratique pour le désactiver.Sans Storyboard:
Usage:
Résultat:
la source
Rembourrage d'une
UILabel
solution complète. Mis à jour pour 2020.Il s'avère qu'il y a trois choses à faire.
1. Doit appeler textRect # forBounds avec la nouvelle taille plus petite
2. Doit remplacer drawText par la nouvelle taille plus petite
3. Si une cellule de taille dynamique, doit ajuster intrinsicContentSize
Dans l'exemple typique ci-dessous, l'unité de texte est dans une vue de table, une vue de pile ou une construction similaire, ce qui lui donne une largeur fixe . Dans l'exemple, nous voulons un rembourrage de 60,20,20,24.
Ainsi, nous prenons le intrinsicContentSize "existant" et ajoutons en fait 80 à la hauteur .
Répéter ...
Je trouve ce processus déroutant, mais c'est ainsi que cela fonctionne. Pour moi, Apple devrait exposer un appel nommé quelque chose comme "calcul préliminaire de la hauteur".
Deuxièmement, nous devons utiliser l'appel textRect # forBounds avec notre nouvelle taille plus petite .
Donc, dans textRect # forBounds, nous réduisons d' abord la taille, puis appelons super.
Alerte! Vous devez appeler super après , pas avant!
Si vous étudiez attentivement toutes les tentatives et discussions sur cette page, c'est exactement le problème. Notez que certaines solutions «semblent presque fonctionner», mais quelqu'un signalera alors que dans certaines situations, cela ne fonctionnera pas. C'est en effet la raison exacte - de façon déroutante, vous devez "appeler super après", pas avant.
Donc, si vous appelez super "dans le mauvais ordre", cela fonctionne généralement, mais pas pour certaines longueurs de texte spécifiques .
Voici un exemple visuel exact de "faire un super premier incorrectement":
Notez que les marges 60,20,20,24 sont correctes MAIS le calcul de la taille est en fait erroné, car il a été fait avec le modèle "super first" dans textRect # forBounds.
Fixé:
Notez que ce n'est que maintenant que le moteur textRect # forBounds sait comment effectuer correctement le calcul :
Finalement!
Là encore, dans cet exemple, le UILabel est utilisé dans la situation typique où la largeur est fixe. Donc, dans intrinsicContentSize, nous devons "ajouter" la hauteur supplémentaire globale que nous voulons. (Vous n'avez pas besoin d '«ajouter» de quelque façon que ce soit à la largeur, cela n'aurait aucun sens car elle est fixée.)
Ensuite, dans textRect # forBounds vous obtenez les limites "suggérées jusqu'ici" par autolayout, vous soustrayez vos marges, et seulement ensuite appelez à nouveau le moteur textRect # forBounds, c'est-à-dire en super, qui vous donnera un résultat.
Enfin et simplement dans drawText, vous dessinez bien sûr dans cette même boîte plus petite.
Phew!
Encore une fois. Notez que les réponses sur ceci et d'autres QA qui sont "presque" correctes souffrent du problème dans la première image ci-dessus - le "super est au mauvais endroit" . Vous devez forcer la taille plus grande dans intrinsicContentSize, puis dans textRect # forBounds, vous devez d'abord réduire les limites de la première suggestion , puis appeler super.
Résumé: vous devez "appeler le super dernier " dans textRect # forBounds
Voilà le secret.
Notez que vous n'avez pas besoin et ne devriez pas avoir besoin d'appeler en plus invalidate, sizeThatFits, needsLayout ou tout autre appel forcé. Une solution correcte devrait fonctionner correctement dans le cycle normal de dessin de mise en page automatique.
Pointe:
Si vous travaillez avec des polices monospaces, voici un bon conseil: https://stackoverflow.com/a/59813420/294884
la source
Swift 4+
usage:
la source
Code Swift 3 avec exemple d'implémentation
N'oubliez pas d'ajouter le nom de classe UIMarginLabel dans l'objet d'étiquette de storyboard. Bon codage!
la source
Selon Swift 4.2 (Xcode 10 beta 6) "UIEdgeInsetsInsetRect" est obsolète. J'ai également déclaré la classe publique pour la rendre plus utile.
la source
sizeToFit()
devrait être public comme: "La méthode d'instance de remplacement doit être aussi accessible que son type englobant"J'ai édité un peu dans la réponse acceptée. Il y a un problème quand
leftInset
etrightInset
augmenter, une partie du texte disparaîtra, b / c la largeur de l'étiquette sera rétrécie mais la hauteur n'augmentera pas comme sur la figure:Pour résoudre ce problème, vous devez recalculer la hauteur du texte comme suit:
et résultat:
J'espère aider certaines personnes dans la même situation que moi.
la source
override func drawTextInRect(rect: CGRect)
devientoverride func drawText(in rect: CGRect)
etoverride func intrinsicContentSize() -> CGSize
devientoverride var intrinsicContentSize : CGSize
Enjoy!override var intrinsicContentSize: CGSize { // .. return intrinsicSuperViewContentSize }
Utilisez simplement la mise en page automatique:
Terminé.
la source
Une autre option sans sous-classement serait de:
text
sizeToFit()
puis augmentez un peu la hauteur de l'étiquette pour simuler le remplissage
la source
label.frame = CGRect( x: label.frame.origin.x - 10, y: label.frame.origin.y - 4, width: label.frame.width + 20,height: label.frame.height + 8)
les -10 et -4 pour la centralisationSolution Swift 3, iOS10:
la source
Dans Swift 3
meilleure et simple manière
la source
Sous-classe UILabel. (File-New-File- CocoaTouchClass-make sous-classe de UILabel).
Sur ViewController:
OU Associez la classe UILabel personnalisée sur Storyboard en tant que classe de Label.
la source
Tout comme les autres réponses mais corrige un bogue. Lorsque
label.width
est contrôlé par la mise en page automatique, parfois le texte sera rogné.la source
Rembourrage facile (Swift 3.0, réponse d'Alvin George):
la source
Une élaboration sur la réponse de Mundi.
c'est-à-dire incorporer une étiquette dans un
UIView
et appliquer le remplissage via la mise en page automatique. Exemple:Aperçu:
1) Créez un
UIView
("panneau") et définissez son apparence.2) Créez un
UILabel
et ajoutez-le au panneau.3) Ajoutez des contraintes pour appliquer le remplissage.
4) Ajoutez le panneau à votre hiérarchie de vues, puis positionnez le panneau.
Détails:
1) Créez la vue de panneau.
2) Créez l'étiquette, ajoutez-la au panneau en tant que sous-vue.
3) Ajoutez des contraintes entre les bords de l'étiquette et le panneau. Cela oblige le panneau à se tenir à distance de l'étiquette. c'est-à-dire "rembourrage"
Éditorial: faire tout cela à la main est très fastidieux, verbeux et sujet aux erreurs. Je vous suggère de choisir un wrapper de mise en page automatique de github ou d'en écrire un vous-même
4) Ajoutez le panneau à votre hiérarchie de vues, puis ajoutez des contraintes de positionnement. par exemple, étreignez le côté droit d'une tableViewCell, comme dans l'exemple d'image.
Remarque: il vous suffit d'ajouter des contraintes de position, pas des contraintes dimensionnelles: la mise en page automatique résoudra la mise en page en fonction à la fois
intrinsicContentSize
de l'étiquette et des contraintes ajoutées précédemment.la source
Utilisez ce code si vous rencontrez un problème de rognage de texte lors de l'application d'un remplissage.
la source
Similaire à d'autres réponses, mais avec une classe func pour configurer le rembourrage de manière dynamique:
la source
Une solution pragmatique consiste à ajouter des étiquettes vierges de même hauteur et couleur que l'étiquette principale. Définissez l'espace de début / de fin de l'étiquette principale sur zéro, alignez les centres verticaux et définissez la largeur de la marge souhaitée.
la source
Si vous souhaitez ajouter un remplissage de 2 pixels autour du textRect, procédez comme suit:
la source
Si vous ne voulez pas ou n'avez pas besoin d'utiliser un UILabel @IBInspectable / @IBDesignable dans Storyboard (je pense que ceux-ci sont rendus trop lentement de toute façon), alors il est plus propre d'utiliser UIEdgeInsets au lieu de 4 CGFloats différents.
Exemple de code pour Swift 4.2:
la source
Objectif c
Basé sur la réponse de Tai Le qui implémente la fonctionnalité dans un IB Designable, voici la version Objective-C.
Mettez ceci dans YourLabel.h
Et cela irait dans YourLabel.m
Vous pouvez ensuite modifier les inserts YourLabel directement dans Interface Builder après avoir spécifié la classe à l'intérieur du XIB ou du storyboard, la valeur par défaut des inserts étant zéro.
la source
Moyen facile
la source
Rembourrage facile:
la source
Swift 4+
la source