59 votes

Définir la hauteur des lignes dans UITextView

Je suis déjà presque sûr que cela ne peut être fait avec aucune API publique, mais je veux quand même demander :

Existe-t-il un moyen de modifier la hauteur des lignes dans une UITextView ?

Il suffirait de le faire de manière statique, sans avoir à le modifier au moment de l'exécution. Le problème est que la hauteur de ligne par défaut est tout simplement beaucoup trop faible. Le texte a l'air extrêmement comprimé et c'est un cauchemar lorsqu'on essaie d'écrire des textes plus longs.

merci, Max

EDIT : Je sais qu'il y a UIWebView et qu'il est beau et peut faire du stylisme, etc. Mais c'est non modifiable . J'ai besoin d'un composant texte éditable avec une hauteur de ligne acceptable. Ce truc de l'Omni Frameworks ne m'aide pas non plus, car il est trop lent et ne me semble pas correct...

112voto

Graham Perks Points 8103

Après iOS 7, l'approche styleString ne fonctionne plus.

Deux nouvelles alternatives sont disponibles.

Tout d'abord, TextKit ; un nouveau moteur de mise en page puissant. Pour modifier l'espacement des lignes, il faut définir le délégué du gestionnaire de mise en page de l'UITextView :

textView.layoutManager.delegate = self; // you'll need to declare you implement the NSLayoutManagerDelegate protocol

Puis remplacez cette méthode déléguée :

- (CGFloat)layoutManager:(NSLayoutManager *)layoutManager lineSpacingAfterGlyphAtIndex:(NSUInteger)glyphIndex withProposedLineFragmentRect:(CGRect)rect
{
    return 20; // For really wide spacing; pick your own value
}

Deuxièmement, iOS 7 prend désormais en charge l'espacement des lignes de NSParagraphStyle. Cela donne encore plus de contrôle, par exemple l'indentation de la première ligne, et le calcul d'un rectangle de délimitation. Donc, alternativement...

NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.headIndent = 15; // <--- indention if you need it
paragraphStyle.firstLineHeadIndent = 15;

paragraphStyle.lineSpacing = 7; // <--- magic line spacing here!

NSDictionary *attrsDictionary =
@{ NSParagraphStyleAttributeName: paragraphStyle }; // <-- there are many more attrs, e.g NSFontAttributeName

self.textView.attributedText = [[NSAttributedString alloc] initWithString:@"Hello World over many lines!" attributes:attrsDictionary];

Pour information, l'ancienne méthode ContentInset permettant d'aligner le texte sur le bord gauche de UITextView est également inutile sous iOS7. Il faut plutôt supprimer la marge :

textView.textContainer.lineFragmentPadding = 0;

5 votes

Le seul problème est que vous ne pouvez pas l'utiliser pour faire la hauteur de la ligne. plus petit

0 votes

Comment calculez-vous la hauteur du texte dans le textview alors ?

0 votes

@TimWachter Avez-vous essayé d'utiliser des valeurs négatives ? Cela fonctionne pour moi.

25voto

mxcl Points 5921

Remarque : cette fonction n'est pas disponible dans iOS7 :


J'ai découvert que vous pouvez créer une sous-classe qui ré-implémente [UITextView styleString] :

@interface UITextView ()
- (id)styleString; // make compiler happy
@end

@interface MBTextView : UITextView
@end
@implementation MBTextView
- (id)styleString {
    return [[super styleString] stringByAppendingString:@"; line-height: 1.2em"];
}
@end

Il ne s'agit pas d'une utilisation privée de l'API : il s'agit simplement d'une sous-classification. Il est possible qu'Apple ne soit pas d'accord bien sûr (bien que considérant la façon dont nous avons tous l'habitude de tout mélanger afin de personnaliser l'apparence de UIKit, je pense que ce genre d'utilisation "privée" n'est pas ce à quoi Apple s'oppose), mais c'est un moyen si facile d'atteindre les objectifs de cette question que vous pouvez aussi bien l'essayer. Si l'application est rejetée, vous pourrez consacrer le temps (probablement important) à une solution plus difficile.

1 votes

Une approche intéressante de la zone grise ;)

0 votes

Cela ne fonctionne pas, UIVIew ne semble pas avoir de styleString.

1 votes

Il fonctionne sur UITextView no UIView . Testé avec iOS 5 dans une application que j'utilise quotidiennement.

19voto

Max Seelemann Points 6345

La seule solution que nous avons trouvée et celle que nous avons choisie : créer une police personnalisée . Cela peut paraître idiot, mais cela semble être la seule solution réaliste.

0 votes

Max Seelemann : Avez-vous déjà trouvé une autre solution à ce problème ou est-ce le seul moyen ? Je suppose que FontLab fera l'affaire et qu'il suffira ensuite de redimensionner la police à la ligne de base pour obtenir un meilleur espacement, non ? Merci !

0 votes

@n.evermind Non, nous utilisons toujours cette solution. Et pour autant que je sache, iOS 5 n'y changera rien...

0 votes

C'est assez ennuyeux. Pensez-vous que CoreText soit une alternative ? Je n'ai pas envie d'apprendre quelque chose de nouveau encore une fois... pour quelque chose d'aussi simple (l'interligne).

10voto

user1172004 Points 157

Le remplacement de styleString par la sous-classe UITextView ne fonctionne que si vous définissez une catégorie sur UITextView qui définit styleString, sinon vous obtenez une erreur de compilation. Par exemple, dans votre sous-classe UITextView :

#import "SomeDangTextView.h"

@interface UITextView ()

- (id)styleString;

@end

@implementation SomeDangTextView

- (id)styleString {
    return [[super styleString] stringByAppendingString:@"; line-height: 1.5em"];
}

@end

0 votes

J'ai déjà essayé la réponse de Max Howell sans succès, j'ai cherché dans la documentation d'Apple pendant un moment et j'ai abandonné. Mais c'est cette solution (définir une catégorie sur UITextView) qui m'a permis d'obtenir un résultat. Merci beaucoup.

0 votes

Cela m'inquiète en tant qu'API non publique (c'est-à-dire privée). Je ne la vois pas documentée : developer.apple.com/library/ios/#DOCUMENTATION/UIKit/Reference/

0 votes

Ça ne marche toujours pas pour moi. Comment définir -(id)styleString dans la catégorie UITextView ?

-1voto

Jordan Points 14134

Selon la documentation d'Apple, vous pouvez utiliser un UIWebView.

Cette classe ne prend pas en charge les styles multiples pour le texte. Les attributs de police, de couleur et d'alignement du texte que vous spécifiez s'appliquent toujours à l'ensemble du contenu de l'affichage du texte. Pour afficher un style plus complexe dans votre application, vous devez utiliser un objet UIWebView et rendre votre contenu à l'aide de HTML.

0 votes

C'est possible si vous interceptez le tap sur la WebView, affichez une UITextView au-dessus, éditez et enregistrez dans la UIWebView ;)

0 votes

C'est vrai, mais comme l'utilisation principale est l'édition, ce n'est toujours pas la meilleure option. Et il y a un autre problème : il est très très difficile (si tant est que cela soit possible) de placer manuellement le point d'insertion dans une UITextView lors d'un événement. Ceci, cependant, serait nécessaire pour changer de vue. :(

0 votes

UITextField adopte UITextInput qui comprend - (UITextPosition *)closestPositionToPoint:(CGPoint)point etc... cela ressemble à ce dont vous avez besoin ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X