web-dev-qa-db-fra.com

iPhone - UILabel contenant du texte avec plusieurs polices en même temps

Je cherche un moyen d'utiliser un UILabel (ou quelque chose de similaire) pour afficher quelque chose comme ceci:

Tom: Un message.

C'est comme la façon dont cela se fait par exemple dans l'application Facebook pour afficher le "qu'est-ce que vous pensez?" messages. Quelqu'un a-t-il des suggestions sur la façon d'aborder cela?

63
Tom van Zummeren

Utilisez deux IBOutlets UILabel, chacun avec un format différent (police/couleur/etc), comme vous le souhaitez. Déplacez le second sur le premier en fonction de l'endroit où se termine le texte du premier. Vous pouvez l'obtenir via sizeWithFont: forWidth: lineBreakMode:

Vous pouvez également sous-classer UILabel et dessiner le texte vous-même dans drawRect. Si vous le faites de cette façon, ajoutez simplement une variable d'instance pour vous indiquer la quantité de chaîne à dessiner dans un format et dessinez le reste dans un autre.

Mise à jour: veuillez consulter la réponse de @ Akshay ci-dessous. Depuis iOS6, UILabel peut contenir NSMutableAttributedString. Quand j'ai écrit cela, ce n'était pas disponible.

18
mahboudz

Il existe un moyen de définir des polices différentes/multiples et d'autres propriétés sur Label à l'aide de NSMutableAttributedString. Foll est mon code:

 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;

Notez que lblText est l'UILabel, sortie en tant que propriétaire du fichier. On peut continuer à ajouter autant de NSMutableAttributedString qu'il veut.

Notez également que j'ai ajouté la police verdana & arial dans mon projet et ajouté une liste pour les mêmes.

103
Akshay

Désolé de la réponse tardive. Le code ci-dessous fonctionne très bien pour moi. Je poste ceci afin qu'il puisse être utile à quelqu'un.

    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;

enter image description here

Veuillez noter que My est semi-gras et que le profil est régulier. J'ai utilisé la police MyRiad. Merci

26
Abdul Yasin

Mise à jour: si vous êtes iOS 6+, utilisez UILabel.attributedText - sinon ....

J'ai créé cette sous-classe de base UIView pour prendre en charge des fonctionnalités similaires.

La liste des éléments pris en charge par pas est plus longue que ce qu'elle fait, mais en gros, elle vous permet de gérer une nique ligne d'étiquettes UIL et de formater chacune comme vous le souhaitez. Cela me permet d'interrompre le texte avec une couleur différente au milieu de la ligne, par exemple, et d'éviter d'utiliser le lourd UIWebView.

Je crée ces objets en plaçant un objet UIView dans mon interface (à l'aide d'Interface Builder) et en définissant le type de l'objet dans IB sur MultipartLabel. Ensuite, dans le code, j'appelle updateNumberOfLabels et les divers sélecteurs setText selon les besoins.

//  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
18
Jason

Dans Swift 2.0 cela peut être fait comme suit

//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

Modifier
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

Modifier
Swift 4.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:
    NSAttributedString.Key.font as NSCopying)
let boldDict:NSDictionary = NSDictionary(object: boldFont, forKey:
    NSAttributedString.Key.font as NSCopying)
let thirdDict:NSDictionary = NSDictionary(object: thirdFont, forKey:
    NSAttributedString.Key.font as NSCopying)

let firstText = "My name is "
let attributedString = NSMutableAttributedString(string: firstText,
                                                         attributes: firstDict as? [NSAttributedString.Key : Any])

let boldText  = "Rajan"
let boldString = NSMutableAttributedString(string:boldText,
                                                   attributes:boldDict as? [NSAttributedString.Key : Any])

let finalText = " iOS"
let finalAttributedString =  NSMutableAttributedString(string:
    finalText, attributes: thirdDict as? [NSAttributedString.Key : Any])

attributedString.append(boldString)
attributedString.append(finalAttributedString)
myLabel.attributedText = attributedString

Cela ressemblera à

enter image description here

14
Rajan Maheshwari

J'ai mis à jour MultipartLabel suggéré par @Jason en ajoutant le support contentMode (alignement du texte).

MultipartLabel.h

#import <Foundation/Foundation.h>

@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
7
Laurynas

Utilisez l'API CoreText, ce sera beaucoup plus rapide.

Voici quelques exemples

Fondamentalement, vous devrez: 1: créer la sous-classe UIView 2: dans la méthode drawRect: ajouter la logique de dessin du texte.

La logique de dessin du texte: - Vous aurez besoin de connaître la plage du "nom" donc si Tom : Un message. est votre chaîne, vous devrez appliquer une police différente pour la plage (0, 3).

Vous pouvez tout personnaliser avec CoreText :)

1
George Petrov

Salut OHAttributelabel est un bon moyen pour cela.Vous pouvez faire référence à un exemple de code avec le lien ci-dessous https://github.com/AliSoftware/OHAttributedLabel Importer le cadre OHAttribute à partir de celui-ci et vous pouvez définir votre étiquette comme ci-dessous

 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];
0
sinh99