iPhone – UILabel contendo texto com várias fonts ao mesmo tempo

Eu estou procurando uma maneira de usar um UILabel (ou algo semelhante) para exibir algo como isto:

Tom: Alguma mensagem.

É como se é feito, por exemplo, no aplicativo do Facebook para exibir o “o que está em sua mente?” mensagens. Alguém tem alguma sugestão de como abordar isso?

Use dois IBOutlets UILabel, cada um com um formato diferente (fonte / cor / etc), como você deseja .. Mova o segundo sobre o primeiro com base em onde termina o texto do primeiro. Você pode obter isso via sizeWithFont: forWidth: lineBreakMode:

Alternativamente, você pode subclassificar o UILabel e desenhar o texto você mesmo no drawRect. Se você fizer dessa maneira, basta adicionar uma variável de instância para informar quanto da sequência desenhar em um formato e desenhar o restante em outra.

Atualização: Por favor, veja a resposta de @Akshay abaixo. A partir do iOS6, o UILabel pode conter NSMutableAttributedString. Quando eu escrevi isso, isso não estava disponível.

Há uma maneira de definir fonts diferentes / múltiplas e outras propriedades no Label usando NSMutableAttributedString. Foll é o meu código:

UIFont *arialFont = [UIFont fontWithName:@"arial" size:18.0]; NSDictionary *arialDict = [NSDictionary dictionaryWithObject: arialFont forKey:NSFontAttributeName]; NSMutableAttributedString *aAttrString = [[NSMutableAttributedString alloc] initWithString:title attributes: arialDict]; UIFont *VerdanaFont = [UIFont fontWithName:@"verdana" size:12.0]; NSDictionary *verdanaDict = [NSDictionary dictionaryWithObject:VerdanaFont forKey:NSFontAttributeName]; NSMutableAttributedString *vAttrString = [[NSMutableAttributedString alloc]initWithString: newsDate attributes:verdanaDict]; [vAttrString addAttribute:NSForegroundColorAttributeName value:[UIColor blackColor] range:(NSMakeRange(0, 15))]; [aAttrString appendAttributedString:vAttrString]; lblText.attributedText = aAttrString; 

Observe que lblText é o UILabel, saída como proprietário do arquivo. Pode-se continuar anexando quantos NSMutableAttributedString ele quiser.

Note também que eu adicionei a fonte verdana & arial no meu projeto e adicionei um plist para o mesmo.

Desculpe pela resposta tardia. Abaixo código funciona muito bem para mim. Estou postando isso para que possa ser útil para alguém.

  UIFont *font1 = [UIFont fontWithName:kMyriadProSemiBold size:15]; NSDictionary *arialDict = [NSDictionary dictionaryWithObject: font1 forKey:NSFontAttributeName]; NSMutableAttributedString *aAttrString1 = [[NSMutableAttributedString alloc] initWithString:@"My" attributes: arialDict]; UIFont *font2 = [UIFont fontWithName:kMyriadProRegular size:15]; NSDictionary *arialDict2 = [NSDictionary dictionaryWithObject: font2 forKey:NSFontAttributeName]; NSMutableAttributedString *aAttrString2 = [[NSMutableAttributedString alloc] initWithString:@"Profile" attributes: arialDict2]; [aAttrString1 appendAttributedString:aAttrString2]; myProfileLabel.attributedText = aAttrString1; 

insira a descrição da imagem aqui

Por favor note que o meu é semibold e o perfil é regular. Eu usei a fonte MyRiad. obrigado

Atualização: Se você é iOS 6+, use UILabel.attributedText – caso contrário ….

Eu criei esta subclass básica do UIView para suportar funcionalidades semelhantes.

A lista de coisas que ele não suporta é mais longa do que o que ele faz, mas basicamente permite que você gerencie uma única linha de UILabels e formate cada qual você quiser. Isso me permite inserir texto com uma cor diferente no meio da linha, por exemplo, e evitar usar o UIWebView pesado.

Eu crio esses objects colocando um object UIView em minha interface (usando o Interface Builder) e definindo o tipo do object em IB para MultipartLabel. Em seguida, no código, chamo updateNumberOfLabels e os vários seletores setText conforme necessário.

 // MultipartLabel.m // MultiLabelLabel // // Created by Jason Miller on 10/7/09. // Copyright 2009 Jason Miller. All rights reserved. // #import "MultipartLabel.h" @interface MultipartLabel (Private) - (void)updateLayout; @end @implementation MultipartLabel @synthesize containerView; @synthesize labels; -(void)updateNumberOfLabels:(int)numLabels; { [containerView removeFromSuperview]; self.containerView = nil; self.containerView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)] autorelease]; [self addSubview:self.containerView]; self.labels = [NSMutableArray array]; while (numLabels-- > 0) { UILabel * label = [[UILabel alloc] initWithFrame:CGRectZero]; [self.containerView addSubview:label]; [self.labels addObject:label]; [label release]; } [self updateLayout]; } -(void)setText:(NSString *)text forLabel:(int)labelNum; { if( [self.labels count] > labelNum && labelNum >= 0 ) { UILabel * thisLabel = [self.labels objectAtIndex:labelNum]; thisLabel.text = text; } [self updateLayout]; } -(void)setText:(NSString *)text andFont:(UIFont*)font forLabel:(int)labelNum; { if( [self.labels count] > labelNum && labelNum >= 0 ) { UILabel * thisLabel = [self.labels objectAtIndex:labelNum]; thisLabel.text = text; thisLabel.font = font; } [self updateLayout]; } -(void)setText:(NSString *)text andColor:(UIColor*)color forLabel:(int)labelNum; { if( [self.labels count] > labelNum && labelNum >= 0 ) { UILabel * thisLabel = [self.labels objectAtIndex:labelNum]; thisLabel.text = text; thisLabel.textColor = color; } [self updateLayout]; } -(void)setText:(NSString *)text andFont:(UIFont*)font andColor:(UIColor*)color forLabel:(int)labelNum; { if( [self.labels count] > labelNum && labelNum >= 0 ) { UILabel * thisLabel = [self.labels objectAtIndex:labelNum]; thisLabel.text = text; thisLabel.font = font; thisLabel.textColor = color; } [self updateLayout]; } - (void)updateLayout { int thisX = 0; // TODO when it is time to support different sized fonts, need to adjust each y value to line up baselines for (UILabel * thisLabel in self.labels) { CGSize size = [thisLabel.text sizeWithFont:thisLabel.font constrainedToSize:CGSizeMake(9999, 9999) lineBreakMode:thisLabel.lineBreakMode]; CGRect thisFrame = CGRectMake( thisX, 0, size.width, size.height ); thisLabel.frame = thisFrame; thisX += size.width; } } - (void)dealloc { [labels release]; labels = nil; [containerView release]; containerView = nil; [super dealloc]; } @end 

Em swift 2.0 isso pode ser feito da seguinte forma

 //Defining fonts of size and type let firstfont:UIFont = UIFont(name: "Helvetica Neue", size: 17)! let boldFont:UIFont = UIFont(name: "HelveticaNeue-Bold", size: 17)! let thirdFont:UIFont = UIFont(name: "HelveticaNeue-ThinItalic", size: 17)! //Making dictionaries of fonts that will be passed as an attribute let firstDict:NSDictionary = NSDictionary(object: firstfont, forKey: NSFontAttributeName) let boldDict:NSDictionary = NSDictionary(object: boldFont, forKey: NSFontAttributeName) let thirdDict:NSDictionary = NSDictionary(object: thirdFont, forKey: NSFontAttributeName) let firstText = "My name is " let attributedString = NSMutableAttributedString(string: firstText, attributes: firstDict as? [String : AnyObject]) let boldText = "Rajan" let boldString = NSMutableAttributedString(string:boldText, attributes:boldDict as? [String : AnyObject]) let finalText = " iOS" let finalAttributedString = NSMutableAttributedString(string: finalText, attributes: thirdDict as? [String : AnyObject]) attributedString.appendAttributedString(boldString) attributedString.appendAttributedString(finalAttributedString) myLabel.attributedText = attributedString 

Editar
Swift 3.0

 let firstfont:UIFont = UIFont(name: "Helvetica Neue", size: 17)! let boldFont:UIFont = UIFont(name: "HelveticaNeue-Bold", size: 17)! let thirdFont:UIFont = UIFont(name: "HelveticaNeue-ThinItalic", size: 17)! //Making dictionaries of fonts that will be passed as an attribute let firstDict:NSDictionary = NSDictionary(object: firstfont, forKey: NSFontAttributeName as NSCopying) let boldDict:NSDictionary = NSDictionary(object: boldFont, forKey: NSFontAttributeName as NSCopying) let thirdDict:NSDictionary = NSDictionary(object: thirdFont, forKey: NSFontAttributeName as NSCopying) let firstText = "My name is " let attributedString = NSMutableAttributedString(string: firstText, attributes: firstDict as? [String : AnyObject]) let boldText = "Rajan" let boldString = NSMutableAttributedString(string:boldText, attributes:boldDict as? [String : AnyObject]) let finalText = " iOS" let finalAttributedString = NSMutableAttributedString(string: finalText, attributes: thirdDict as? [String : AnyObject]) attributedString.append(boldString) attributedString.append(finalAttributedString) myLabel.attributedText = attributedString 

Isso vai parecer

insira a descrição da imagem aqui

Atualizei o MultipartLabel sugerido pelo @Jason adicionando o suporte contentMode (alinhamento de texto).

MultipartLabel.h

 #import  @interface MultipartLabel : UIView { } @property (nonatomic,retain) UIView *containerView; @property (nonatomic,retain) NSMutableArray *labels; @property (nonatomic) UIViewContentMode contentMode; - (void)updateNumberOfLabels:(int)numLabels; - (void)setText:(NSString *)text forLabel:(int)labelNum; - (void)setText:(NSString *)text andFont:(UIFont*)font forLabel:(int)labelNum; - (void)setText:(NSString *)text andColor:(UIColor*)color forLabel:(int)labelNum; - (void)setText:(NSString *)text andFont:(UIFont*)font andColor:(UIColor*)color forLabel:(int)labelNum; @end 

MultipartLabel.m

 // MultipartLabel.m // MultipartLabel // // Created by Jason Miller on 10/7/09. // Updated by Laurynas Butkus, 2011 // Copyright 2009 Jason Miller. All rights reserved. // #import "MultipartLabel.h" @interface MultipartLabel (Private) - (void)updateLayout; @end @implementation MultipartLabel @synthesize containerView; @synthesize labels; @synthesize contentMode; -(void)updateNumberOfLabels:(int)numLabels { [containerView removeFromSuperview]; self.containerView = nil; self.containerView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)] autorelease]; [self addSubview:self.containerView]; self.labels = [NSMutableArray array]; while (numLabels-- > 0) { UILabel * label = [[UILabel alloc] initWithFrame:CGRectZero]; label.backgroundColor = self.backgroundColor; [self.containerView addSubview:label]; [self.labels addObject:label]; [label release]; } [self updateLayout]; } -(void)setText:(NSString *)text forLabel:(int)labelNum { if( [self.labels count] > labelNum && labelNum >= 0 ) { UILabel * thisLabel = [self.labels objectAtIndex:labelNum]; thisLabel.text = text; } [self updateLayout]; } -(void)setText:(NSString *)text andFont:(UIFont*)font forLabel:(int)labelNum { if( [self.labels count] > labelNum && labelNum >= 0 ) { UILabel * thisLabel = [self.labels objectAtIndex:labelNum]; thisLabel.text = text; thisLabel.font = font; } [self updateLayout]; } -(void)setText:(NSString *)text andColor:(UIColor*)color forLabel:(int)labelNum { if( [self.labels count] > labelNum && labelNum >= 0 ) { UILabel * thisLabel = [self.labels objectAtIndex:labelNum]; thisLabel.text = text; thisLabel.textColor = color; } [self updateLayout]; } - (void)setText:(NSString *)text andFont:(UIFont*)font andColor:(UIColor*)color forLabel:(int)labelNum { if( [self.labels count] > labelNum && labelNum >= 0 ) { UILabel * thisLabel = [self.labels objectAtIndex:labelNum]; thisLabel.text = text; thisLabel.font = font; thisLabel.textColor = color; } [self updateLayout]; } - (void)updateLayout { int thisX; int thisY; int totalWidth = 0; int offsetX = 0; int sizes[[self.labels count]][2]; int i = 0; for (UILabel * thisLabel in self.labels) { CGSize size = [thisLabel.text sizeWithFont:thisLabel.font constrainedToSize:CGSizeMake(9999, 9999) lineBreakMode:thisLabel.lineBreakMode]; sizes[i][0] = size.width; sizes[i][1] = size.height; totalWidth+= size.width; i++; } i = 0; for (UILabel * thisLabel in self.labels) { // X switch (self.contentMode) { case UIViewContentModeRight: case UIViewContentModeBottomRight: case UIViewContentModeTopRight: thisX = self.frame.size.width - totalWidth + offsetX; break; case UIViewContentModeCenter: thisX = (self.frame.size.width - totalWidth) / 2 + offsetX; break; default: thisX = offsetX; break; } // Y switch (self.contentMode) { case UIViewContentModeBottom: case UIViewContentModeBottomLeft: case UIViewContentModeBottomRight: thisY = self.frame.size.height - sizes[i][1]; break; case UIViewContentModeCenter: thisY = (self.frame.size.height - sizes[i][1]) / 2; break; default: thisY = 0; break; } thisLabel.frame = CGRectMake( thisX, thisY, sizes[i][0], sizes[i][1] ); offsetX += sizes[i][0]; i++; } } - (void)dealloc { [labels release]; labels = nil; [containerView release]; containerView = nil; [super dealloc]; } @end 

Use a API do CoreText, será muito mais rápido.

Aqui estão alguns exemplos

Basicamente, as coisas que você terá que fazer são: 1: Criar subclass UIView 2: No método drawRect: add, adicione a lógica de desenho de texto.

A lógica do desenho de texto: – Você precisará saber o alcance do “nome”, portanto, se Tom : Alguma mensagem. é a sua string, você terá que aplicar uma fonte diferente para o intervalo (0, 3).

Você pode personalizar tudo com o CoreText 🙂

Olá OHAttribucanvasbel é uma boa maneira para isso.Você pode consultar o código de exemplo com o link abaixo https://github.com/AliSoftware/OHAttributedLabel Importe o framwork OHAttribute dele e você pode definir seu label como abaixo

  OHAttributedLabel *lblText; lblText = [[OHAttributedLabel alloc] initWithFrame:CGRectMake(10,10,100,19)]; lblText.backgroundColor = [UIColor clearColor]; lblText.textAlignment = UITextAlignmentCenter; lblText.font = [UIFont fontWithName:@"BoschSans-Regular" size:10]; NSString *strText=@"Tom: Some message."; NSMutableAttributedString* attrStr = [NSMutableAttributedString attributedStringWithString: strText]; NSRange rangeOfSubstring = [strVersion rangeOfString:@“Tom:]; if (rangeOfSubstring.location != NSNotFound) { [attrStr setFontName:@"BoschSans-BOLD" size:10.0 range:rangeOfSubstring]; } else { } lblText.attributedText = attrStr; [self.View addSubview: lblText]; 

Uma opção seria usar um UIWebView em vez de UILabel.

Um exemplo: http://iphoneincubator.com/blog/windows-views/display-rich-text-using-a-uiwebview

é muito fácil criar seu próprio código HTML =>

 UIWebView *titleAd = [UIWebView alloc] init...; NSString *cssString = [NSString stringWithFormat:@".title {font-family: HelveticaNeue; text-decoration: bold; font-size: %fpt; color: #4083a9;} .author {font-family: HelveticaNeue; text-decoration: bold; font-size: %fpt; color: #3e4545;}",__FONTSIZE_29__, __FONTSIZE_21__]; NSString *htmlString = [NSString stringWithFormat:@"     

%@ proposé par %@

", cssString, [table title], [table nameOwner]]; [titleAd loadHTMLString:htmlString baseURL:nil];