web-dev-qa-db-fra.com

Centrer verticalement dans UILabel avec rétrécissement automatique

Ceci est un peu différent de toutes les autres questions "Comment puis-je centrer le texte dans un UILabel" ici ...

J'ai un UILabel avec du texte dedans, je veux centrer le texte verticalement dans le UILabel. Quel est le gros problème, non? C'est la valeur par défaut. Le problème vient du fait que mon texte est dynamique et que le rétrécissement automatique est activé. À mesure que le texte s'agrandit, la taille de la police diminue. Vous obtenez ce comportement.

enter image description here

Notez que la ligne de base de la police n'a pas bougé, je veux qu'elle bouge pour que les nombres soient centrés verticalement dans le UILabel's Cadre.

Facile, non? Je me souviens juste du centre d'origine du cadre dans viewDidLoad

    self.workoutTimeCenter = _workoutTimeLabel.center;

puis j'appelle sizeToFit après avoir changé le texte, non?

    [_workoutTimeLabel sizeToFit];
    _workoutTimeLabel.center = _workoutTimeCenter;

Eh bien, sizeToFit a, je suppose, exactement ce qu'il était censé faire, redimensionner le cadre pour que le texte tienne sans rétrécir!

enter image description here

Comment centrer verticalement le texte dans un UILabel tout en respectant les lignes de base et le rétrécissement automatique? (Remarque, une solution iOS5 et ultérieure est très bien et je peux même gérer une solution iOS6 et ultérieure.)

45
Paul Cezanne

D'après mon expérience, vous pouvez simplement définir le -[UILabel baselineAdjustment] propriété à UIBaselineAdjustmentAlignCenters pour obtenir l'effet que vous décrivez.

De la docs :

ajustement de référence

Contrôle la façon dont les lignes de base du texte sont ajustées lorsque le texte doit se réduire pour tenir dans l'étiquette.

@property(nonatomic) UIBaselineAdjustment baselineAdjustment

Discussion

Si la propriété adjustsFontSizeToFitWidth est définie sur YES, cette propriété contrôle le comportement des lignes de base de texte dans les situations où un ajustement de la taille de police est requis. La valeur par défaut de cette propriété est UIBaselineAdjustmentAlignBaselines. Cette propriété n'est effective que lorsque la propriété numberOfLines est définie sur 1.

et

UIBaselineAdjustmentAlignCenters
Ajustez le texte en fonction du centre de son cadre de sélection.

EDIT: ajout d'un contrôleur de vue complet qui le démontre:

@interface TSViewController : UIViewController
@end

@implementation TSViewController

- (void) addLabelWithFrame: (CGRect) f baselineAdjustment: (UIBaselineAdjustment) bla
{
    UILabel* label = [[UILabel alloc] initWithFrame: f];
    label.baselineAdjustment = bla;
    label.adjustsFontSizeToFitWidth = YES;
    label.font = [UIFont fontWithName: @"Courier" size: 200];
    label.text = @"00";
    label.textAlignment = NSTextAlignmentCenter;
    label.backgroundColor = [UIColor lightGrayColor];
    label.userInteractionEnabled = YES;
    [self.view addSubview: label];

    UIView* centerline = [[UIView alloc] initWithFrame: CGRectMake(f.Origin.x, f.Origin.y+(f.size.height/2.0), f.size.width, 1)];
    centerline.backgroundColor = [UIColor redColor];
    [self.view addSubview: centerline];

    UITapGestureRecognizer* tgr = [[UITapGestureRecognizer alloc] initWithTarget: self action: @selector(onTap:)];
    [label addGestureRecognizer: tgr];
}

- (void) viewDidLoad
{
    [super viewDidLoad];

    [self addLabelWithFrame: CGRectMake(0, 0, 320, 200)
         baselineAdjustment: UIBaselineAdjustmentAlignCenters];

    [self addLabelWithFrame: CGRectMake(0, 220, 320, 200)
         baselineAdjustment: UIBaselineAdjustmentAlignBaselines];
}

- (void) onTap: (UITapGestureRecognizer*) tgr
{
    UILabel* label = (UILabel*)tgr.view;
    NSString* t = [label.text stringByAppendingString: @":00"];
    label.text = t;
}

@end
93
TomSwift

lorsque vous travaillez dans IB, assurez-vous de définir l'alignement des lignes de base au centre

enter image description here

Remarque: le saut de ligne NE PEUT PAS être un retour à la ligne pour que cela fonctionne, il ne fonctionnera donc PAS sur plusieurs lignes (bon pour définir le saut de ligne sur Tronquer la queue)

3
Peter Lapisu
-(void)fitVerticallyToLabel:(UILabel *)lbl
{
    CGFloat fontSize = lbl.frame.size.width / lbl.text.length;
    [lbl setFont:[UIFont fontWithName:@"Helvetica-Bold" size:fontSize]];

    CGRect rect = lbl.frame;
    rect.Origin.y += rect.size.height - fontSize;
    rect.size.height = fontSize;
    [lbl setFrame:rect];
}

Comment utiliser: appelez cette méthode après avoir défini le texte sur votre étiquette.

    label.text = @"text";
    [self fitVerticallyToLabel:label];

enter image description hereenter image description here

Remarque: j'ai pris UILabel de xib. Vous pouvez également le prendre par programme dans ce cas, vous devrez définir l'alignement du texte NSTextAlignMentCenter

2
TheTiger

Essayez d'implémenter cette logique:

-(void)adjustLabel1Text1:(NSString *)text1 
{
    UILabel *lbl_first = [UIFont fontWithName:@"Helvetica" size:12];



    text1 = [text1 stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];


    float hedingLblHeight = [self calculateHeightOfTextFromWidth:text1 : [UIFont fontWithName:@"Helvetica" size:12] :118 :UILineBreakModeWordWrap];

    lbl_first.text=text1;


    [lbl_first setFrame:CGRectMake(lbl_first.frame.Origin.x, lbl_first.frame.Origin.y, 118, hedingLblHeight)];
    lbl_first.lineBreakMode = UILineBreakModeWordWrap;
    lbl_first.numberOfLines = 0;
    [lbl_first sizeToFit];




//////////Adjust the lable or any UIControl below this label accordingly.

    float endResultHeight=[self calculateHeightOfTextFromWidth:text2 : [UIFont fontWithName:@"Helvetica" size:15] :299 :UILineBreakModeWordWrap];

    if(hedingLblHeight>secondImgTitleHeight)
    {
    [lbl_endResult setFrame:CGRectMake(lbl_endResult.frame.Origin.x, lbl_first.frame.Origin.y+lbl_first.frame.size.height+5, 299, endResultHeight)];
    }
    else
    {
        [lbl_endResult setFrame:CGRectMake(lbl_endResult.frame.Origin.x, lbl_first.frame.Origin.y+lbl_first.frame.size.height+5, 299, endResultHeight)];

    }

    lbl_endResult.lineBreakMode=UILineBreakModeWordWrap;
    lbl_endResult.numberOfLines = 0;
    [lbl_endResult sizeToFit];



}

-(float) calculateHeightOfTextFromWidth:(NSString*)text : (UIFont*) withFont:(float)width :(UILineBreakMode)lineBreakMode
{

    CGSize suggestedSize = [text sizeWithFont:withFont constrainedToSize:CGSizeMake(width, FLT_MAX) lineBreakMode:lineBreakMode];

    return suggestedSize.height;
}

Cela m'a beaucoup aidé, j'espère que cela fonctionne pour vous.

1
Aniket Kote