Comment souligner un texte qui peut être composé de plusieurs lignes de chaîne? Je trouve que certaines personnes suggèrent UIWebView, mais c'est évidemment une classe trop lourde pour le rendu de texte.
Mes pensées étaient de déterminer le point de départ et la longueur de chaque chaîne dans chaque ligne. Et tracez une ligne en dessous en conséquence.
Je rencontre des problèmes pour déterminer la longueur et le point de départ de la chaîne.
J'ai essayé d'utiliser -[UILabel textRectForBounds:limitedToNumberOfLines:]
, cela devrait être le rectangle de délimitation du dessin pour le texte, n'est-ce pas? Alors je dois travailler sur l'alignement? Comment puis-je obtenir le point de départ de chaque ligne lorsqu'elle est justifiée au centre et à droite?
Réponses:
Vous pouvez sous-classer à partir de UILabel et remplacer la méthode drawRect:
- (void)drawRect:(CGRect)rect { CGContextRef ctx = UIGraphicsGetCurrentContext(); CGContextSetRGBStrokeColor(ctx, 207.0f/255.0f, 91.0f/255.0f, 44.0f/255.0f, 1.0f); // RGBA CGContextSetLineWidth(ctx, 1.0f); CGContextMoveToPoint(ctx, 0, self.bounds.size.height - 1); CGContextAddLineToPoint(ctx, self.bounds.size.width, self.bounds.size.height - 1); CGContextStrokePath(ctx); [super drawRect:rect]; }
UPD:
À partir d'iOS 6, Apple a ajouté la prise en charge de NSAttributedString pour UILabel, donc maintenant c'est beaucoup plus facile et fonctionne pour plusieurs lignes:
NSDictionary *underlineAttribute = @{NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle)}; myLabel.attributedText = [[NSAttributedString alloc] initWithString:@"Test string" attributes:underlineAttribute];
Si vous souhaitez toujours prendre en charge iOS 4 et iOS 5, je vous recommande d'utiliser TTTAttributedLabel plutôt que de souligner l'étiquette manuellement. Cependant, si vous devez souligner UILabel sur une ligne et ne voulez pas utiliser de composants tiers, le code ci-dessus fera toujours l'affaire.
la source
Dans Swift:
let underlineAttriString = NSAttributedString(string: "attriString", attributes: [NSAttributedString.Key.underlineStyle: NSUnderlineStyle.single.rawValue]) label.attributedText = underlineAttriString
la source
C'est ce que j'ai fait. Cela fonctionne comme du beurre.
1) Ajoutez CoreText.framework à vos Frameworks.
2) importez <CoreText / CoreText.h> dans la classe où vous avez besoin d'une étiquette soulignée.
3) Écrivez le code suivant.
NSMutableAttributedString *attString = [[NSMutableAttributedString alloc] initWithString:@"My Messages"]; [attString addAttribute:(NSString*)kCTUnderlineStyleAttributeName value:[NSNumber numberWithInt:kCTUnderlineStyleSingle] range:(NSRange){0,[attString length]}]; self.myMsgLBL.attributedText = attString; self.myMsgLBL.textColor = [UIColor whiteColor];
la source
Utilisez une chaîne d'attribut:
NSMutableAttributedString* attrString = [[NSMutableAttributedString alloc] initWithString:@"Your String"] [attrString addAttribute:(NSString*)kCTUnderlineStyleAttributeName value:[NSNumber numberWithInt:kCTUnderlineStyleSingle] range:(NSRange){0,[attrString length]}];
Et puis remplacez l'étiquette - (void) drawTextInRect: (CGRect) aRect et restituer le texte dans quelque chose comme:
CGContextRef ctx = UIGraphicsGetCurrentContext(); CGContextSaveGState(ctx); CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)attrString); drawingRect = self.bounds; CGMutablePathRef path = CGPathCreateMutable(); CGPathAddRect(path, NULL, drawingRect); textFrame = CTFramesetterCreateFrame(framesetter,CFRangeMake(0,0), path, NULL); CGPathRelease(path); CFRelease(framesetter); CTFrameDraw(textFrame, ctx); CGContextRestoreGState(ctx);
Ou mieux encore, au lieu de remplacer, utilisez simplement le OHAttributedLabel créé par Olivier Halligon
la source
NSMutableAttributedString
J'ai combiné certaines des réponses fournies, pour créer une meilleure sous-classe UILabel (au moins pour mes besoins), qui prend en charge:
https://github.com/GuntisTreulands/UnderLineLabel
la source
Les personnes qui ne veulent pas sous-classer la vue (UILabel / UIButton) etc ... 'forgetButton' peut également être remplacé par n'importe quelle étiquette.
-(void) drawUnderlinedLabel { NSString *string = [forgetButton titleForState:UIControlStateNormal]; CGSize stringSize = [string sizeWithFont:forgetButton.titleLabel.font]; CGRect buttonFrame = forgetButton.frame; CGRect labelFrame = CGRectMake(buttonFrame.origin.x + buttonFrame.size.width - stringSize.width, buttonFrame.origin.y + stringSize.height + 1 , stringSize.width, 2); UILabel *lineLabel = [[UILabel alloc] initWithFrame:labelFrame]; lineLabel.backgroundColor = [UIColor blackColor]; //[forgetButton addSubview:lineLabel]; [self.view addSubview:lineLabel]; }
la source
NSString *tem =self.detailCustomerCRMCaseLabel.text; if (tem != nil && ![tem isEqualToString:@""]) { NSMutableAttributedString *temString=[[NSMutableAttributedString alloc]initWithString:tem]; [temString addAttribute:NSUnderlineStyleAttributeName value:[NSNumber numberWithInt:1] range:(NSRange){0,[temString length]}]; self.detailCustomerCRMCaseLabel.attributedText = temString; }
la source
Une autre solution pourrait être (depuis iOS 7) une valeur négative à
NSBaselineOffsetAttributeName
, par exemple votreNSAttributedString
pourrait être:NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:@"my text goes here' attributes:@{NSFontAttributeName: [UIFont fontWithName:@"Helvetica-Regular" size:12], NSForegroundColorAttributeName: [UIColor blackColor], NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle), NSBaselineOffsetAttributeName: @(-3)}];
J'espère que cela aidera ;-)
la source
NSMutableAttributedString *text = [self.myUILabel.attributedText mutableCopy]; [text addAttribute:NSUnderlineStyleAttributeName value:@(NSUnderlineStyleSingle) range:NSMakeRange(0, text.length)]; self.myUILabel.attributedText = text;
la source
Vous pouvez créer une étiquette personnalisée avec le nom UnderlinedLabel et modifier la fonction drawRect.
#import "UnderlinedLabel.h" @implementation UnderlinedLabel - (void)drawRect:(CGRect)rect { NSString *normalTex = self.text; NSDictionary *underlineAttribute = @{NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle)}; self.attributedText = [[NSAttributedString alloc] initWithString:normalTex attributes:underlineAttribute]; [super drawRect:rect]; }
la source
Voici la solution la plus simple qui fonctionne pour moi sans écrire de codes supplémentaires.
// To underline text in UILable NSMutableAttributedString *text = [[NSMutableAttributedString alloc] initWithString:@"Type your text here"]; [text addAttribute:NSUnderlineStyleAttributeName value:@(NSUnderlineStyleSingle) range:NSMakeRange(0, text.length)]; lblText.attributedText = text;
la source
Parfois, nous développeur coincé dans une petite partie de conception de n'importe quel écran d'interface utilisateur. L'une des exigences les plus irritantes est le texte en ligne. Ne vous inquiétez pas, voici la solution.
Souligner un texte dans un UILabel à l'aide de l'Objectif C
UILabel *label=[[UILabel alloc]initWithFrame:CGRectMake(0, 0, 320, 480)]; label.backgroundColor=[UIColor lightGrayColor]; NSMutableAttributedString *attributedString; attributedString = [[NSMutableAttributedString alloc] initWithString:@"Apply Underlining"]; [attributedString addAttribute:NSUnderlineStyleAttributeName value:@1 range:NSMakeRange(0, [attributedString length])]; [label setAttributedText:attributedString];
Souligner un texte dans UILabel à l'aide de Swift
label.backgroundColor = .lightGray let attributedString = NSMutableAttributedString.init(string: "Apply UnderLining") attributedString.addAttribute(NSUnderlineStyleAttributeName, value: 1, range: NSRange.init(location: 0, length: attributedString.length)) label.attributedText = attributedString
la source
Une version améliorée du code de Kovpas (couleur et taille de ligne)
@implementation UILabelUnderlined - (void)drawRect:(CGRect)rect { CGContextRef ctx = UIGraphicsGetCurrentContext(); const CGFloat* colors = CGColorGetComponents(self.textColor.CGColor); CGContextSetRGBStrokeColor(ctx, colors[0], colors[1], colors[2], 1.0); // RGBA CGContextSetLineWidth(ctx, 1.0f); CGSize tmpSize = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(200, 9999)]; CGContextMoveToPoint(ctx, 0, self.bounds.size.height - 1); CGContextAddLineToPoint(ctx, tmpSize.width, self.bounds.size.height - 1); CGContextStrokePath(ctx); [super drawRect:rect]; } @end
la source
J'ai créé pour uilabel multiligne avec soulignement:
Pour les tailles de police 8 à 13, définissez int lineHeight = self.font.pointSize + 3;
Pour les tailles de police de 14 à 20, définissez int lineHeight = self.font.pointSize + 4;
- (void)drawRect:(CGRect)rect { CGContextRef ctx = UIGraphicsGetCurrentContext(); const CGFloat* colors = CGColorGetComponents(self.textColor.CGColor); CGContextSetRGBStrokeColor(ctx, colors[0], colors[1], colors[2], 1.0); // RGBA CGContextSetLineWidth(ctx, 1.0f); CGSize tmpSize = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(self.frame.size.width, 9999)]; int height = tmpSize.height; int lineHeight = self.font.pointSize+4; int maxCount = height/lineHeight; float totalWidth = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(1000, 9999)].width; for(int i=1;i<=maxCount;i++) { float width=0.0; if((i*self.frame.size.width-totalWidth)<=0) width = self.frame.size.width; else width = self.frame.size.width - (i* self.frame.size.width - totalWidth); CGContextMoveToPoint(ctx, 0, lineHeight*i-1); CGContextAddLineToPoint(ctx, width, lineHeight*i-1); } CGContextStrokePath(ctx); [super drawRect:rect]; }
la source
Comme kovpas l'a montré, vous pouvez utiliser le cadre de sélection dans la plupart des cas, bien qu'il ne soit pas toujours garanti que le cadre de sélection s'adapte parfaitement au texte. Une boîte avec une hauteur de 50 et une taille de police de 12 peut ne pas donner les résultats souhaités selon la configuration d'UILabel.
Interrogez l'UIString dans UILabel pour déterminer ses métriques exactes et utilisez-les pour mieux placer votre soulignement quel que soit le cadre ou le cadre englobant en utilisant le code de dessin déjà fourni par kovpas.
Vous devriez également regarder la propriété «principale» d'UIFont qui donne la distance entre les lignes de base en fonction d'une police particulière. La ligne de base est l'endroit où vous souhaitez que votre soulignement soit dessiné.
Recherchez les ajouts UIKit à NSString:
(CGSize)sizeWithFont:(UIFont *)font //Returns the size of the string if it were to be rendered with the specified font on a single line. (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size // Returns the size of the string if it were rendered and constrained to the specified size. (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size lineBreakMode:(UILineBreakMode)lineBreakMode //Returns the size of the string if it were rendered with the specified constraints.
la source
J'utilise une vue de ligne open source et je viens de l'ajouter aux sous-vues de bouton:
UILabel *label = termsButton.titleLabel; CGRect frame = label.frame; frame.origin.y += frame.size.height - 1; frame.size.height = 1; SSLineView *line = [[SSLineView alloc] initWithFrame:frame]; line.lineColor = [UIColor lightGrayColor]; [termsButton addSubview:line];
Cela a été inspiré par Karim ci-dessus.
la source
Basé sur les réponses de Kovpas et Damien Praca, voici une implémentation de UILabelUnderligned qui supporte également textAlignemnt .
#import <UIKit/UIKit.h> @interface UILabelUnderlined : UILabel @end
et la mise en œuvre:
#import "UILabelUnderlined.h" @implementation DKUILabel - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { // Initialization code } return self; } - (void)drawRect:(CGRect)rect { CGContextRef ctx = UIGraphicsGetCurrentContext(); const CGFloat* colors = CGColorGetComponents(self.textColor.CGColor); CGContextSetRGBStrokeColor(ctx, colors[0], colors[1], colors[2], 1.0); // RGBA CGContextSetLineWidth(ctx, 1.0f); CGSize textSize = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(200, 9999)]; // handle textAlignement int alignementXOffset = 0; switch (self.textAlignment) { case UITextAlignmentLeft: break; case UITextAlignmentCenter: alignementXOffset = (self.frame.size.width - textSize.width)/2; break; case UITextAlignmentRight: alignementXOffset = self.frame.size.width - textSize.width; break; } CGContextMoveToPoint(ctx, alignementXOffset, self.bounds.size.height - 1); CGContextAddLineToPoint(ctx, alignementXOffset+textSize.width, self.bounds.size.height - 1); CGContextStrokePath(ctx); [super drawRect:rect]; } @end
la source
Voici une autre solution plus simple (la largeur du soulignement n'est pas la plus précise mais c'était assez bon pour moi)
J'ai un UIView
(_view_underline)
qui a un fond blanc, une hauteur de 1 pixel et je mets à jour sa largeur à chaque fois que je mets à jour le texte// It's a shame you have to do custom stuff to underline text - (void) underline { float width = [[_txt_title text] length] * 10.0f; CGRect prev_frame = [_view_underline frame]; prev_frame.size.width = width; [_view_underline setFrame:prev_frame]; }
la source
NSUnderlineStyleAttributeName qui prend un NSNumber (où 0 n'est pas souligné) peut être ajouté à un dictionnaire d'attributs. Je ne sais pas si c'est plus facile. Mais c'était plus facile pour mes besoins.
NSDictionary *attributes; attributes = @{NSFontAttributeName:font, NSParagraphStyleAttributeName: style, NSUnderlineStyleAttributeName:[NSNumber numberWithInteger:1]}; [text drawInRect:CGRectMake(self.contentRect.origin.x, currentY, maximumSize.width, textRect.size.height) withAttributes:attributes];
la source
Swift 4.1 ver:
let underlineAttriString = NSAttributedString(string:"attriString", attributes: [NSAttributedStringKey.underlineStyle: NSUnderlineStyle.styleSingle.rawValue]) label.attributedText = underlineAttriString
la source
Vous pouvez utiliser cette étiquette personnalisée! Vous pouvez également utiliser le générateur d'interface pour définir
import UIKit class YHYAttributedLabel : UILabel{ @IBInspectable var underlineText : String = ""{ didSet{ self.attributedText = NSAttributedString(string: underlineText, attributes: [NSAttributedString.Key.underlineStyle: NSUnderlineStyle.single.rawValue]) } } }
la source