关于UILabel的属性与布局的一些体会

UILabel 是我在第一次上手项目中,用得最多的一个控件。非常多的地方需要用它来显示文本信息。

通常需要绘制它的Frame、设置它的字体、颜色等等。最常见遇到的问题时,该如何去设置文本的大小以及位置,如果美工已经明确给出了视觉效果图,那么对于字体的大小,颜色都可以十分容易的进行设置了。而位置仍然是一个十分头疼的问题。

本文将主要就Text Attributes 和 Layout UILabel 来说一下我的体会。

Accessing the Text Attributes

首先,我们来看一下UILable的常见属性。

objectivecUILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(0, 120, 32]0, 30)];
label.text = @"文本内容文本内容文本内容";
label.attributedText = [[NSAttributedString alloc]initWithString:@"属性文本属性文本"];
label.font = [UIFont systemFontOfSize:15.0f];
label.textColor = [UIColor blackColor];
//文本的在文本框的显示位置
label.textAlignment = NSTextAlignmentLeft;
//文字过长时的现实方式
label.lineBreakMode = NSLineBreakByWordWrapping;
//文本框是否允许多行(布局相关)
label.numberOfLines = 0;
//设置是否是高亮
label.highlighted=YES;
//高亮颜色
label.highlightedTextColor=[UIColor redColor];
//设置阴影颜色
label.shadowColor=[UIColor blueColor];
//阴影偏移量
label.shadowOffset=CGSizeMake(0.5, 0.5);

其中大多数属性都是非常容易理解的。这里简单提一下其中的几个属性的枚举值。

NSTextAlignment

NSTextAlignmentLeft //左对齐
NSTextAlignmentCenter //居中
NSTextAlignmentRight //右对齐
NSTextAlignmentJustified//最后一行自然对齐
NSTextAlignmentNatural //默认对齐脚本

NSLineBreakMode

NSLineBreakByWordWrapping = 0,//以空格为边界,保留单词
NSLineBreakByCharWrapping, //保留整个字符
NSLineBreakByClipping, //简单剪裁,到边界为止
NSLineBreakByTruncatingHead, //按照”……文字”显示
NSLineBreakByTruncatingTail, //按照”文字……文字”显示
NSLineBreakByTruncatingMiddle //按照”文字……”显示

首先设置UILabel的Frame,然后设置以上属性,我们便可以得到你想要的文本框。

问题来了 每次都这样配置好麻烦啊,有没有默认配置?

这个自然是有的,就比如我只写了frame与text属性,UILabel也会有默认的样式来显示内容。但是在开发中,特别是当没有UI给定我们字体的样式时,如何设计出正常的(不丑)的文本样式呢?那么,就用系统的默认字体吧。

objectivec UIFont *bodyFont = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];

我们将bodyFont设置成了UIFontStyleBody,系统不仅提供了body的字体,还有更多其他的:

objectivecNSString *const UIFontTextStyleHeadline;
NSString *const UIFontTextStyleSubheadline;
NSString *const UIFontTextStyleBody;
NSString *const UIFontTextStyleFootnote;
NSString *const UIFontTextStyleCaption1;
NSString *const UIFontTextStyleCaption2;

在不同位置使用不同的默认字体,这样是不是能够省去一些设计的麻烦呢。
当然我们也可以对获取到的默认格式字体,进行修改,下面的代码中,我向UIFontTextStyleBody中追加了加粗效果。

objectivecUIFontDescriptor *existingDescriptor = [bodyFont fontDescriptor];
UIFontDescriptorSymbolicTraits traints = existingDescriptor.symbolicTraits;
traints |= UIFontDescriptorTraitBold;
UIFontDescriptor *bodyBoldDescriptor = [existingDescriptor fontDescriptorWithSymbolicTraits:traints];

UIFont *boldBodyFont = [UIFont fontWithDescriptor:bodyBoldDescriptor size:0];

其中使用的UIFontDescriptor类,苹果的官方解释相信非常好理解。

UIFontDescriptor objects provide a mechanism to describe a font with a dictionary of attributes. This font descriptor can be used later to create or modify a UIFont object.

那么通过这个类,我们就可以创建或者改造一个字体对象了。当然可供改造的属性很多,这里就不一一介绍了,因为很多我也没有尝试过。

问题又来了 文本样式就不能丰富一点么?

关于文本框的样式,简单来说,就是文本框可以显示“艺术字”么?UILabel提供了attributedText属性,让我们为UILabel设置Attributed字体。
简单来说,过程是这样的:

objectivec  UILabel *lbl2 = [[UILabel alloc] initWithFrame:CGRectMake(0, 220, 320, 30)];
  NSString *str = @"为Label设置属性字符串";
  NSDictionary *fontAttributeDic = @{NSFontAttributeName:[UIFont preferredFontForTextStyle:UIFontTextStyleBody],
                                       NSForegroundColorAttributeName:[UIColor blueColor],
                                       NSStrokeColorAttributeName:[UIColor orangeColor],
                                       NSStrokeWidthAttributeName: @(-5),
                                       NSUnderlineStyleAttributeName: @(NSUnderlineStyleDouble),
                                       NSUnderlineColorAttributeName: [UIColor blackColor]};
  NSMutableAttributedString *mutableAttributedStr = [[NSMutableAttributedString alloc]initWithString:str attributes:fontAttributeDic];
  lbl2.attributedText = mutableAttributedStr;
  [self.view addSubview:lbl2];

代码中我们首先做了一个字典,字典中包含了我需要的属性字符串的AttributeName。其中有前景色、边缘色、边缘宽度(设置为-5,就表示边缘在字体内部了)、下划线类型、下划线颜色等等。

Tips:当同时设置了label.text 与 label.attributedText 时,以后设置的为准。

也就是说

objectiveclabel.Text = @"aaaaa";
label.attributedText = @"bbbbb" ;

最后显示在界面上的,会是attributedText,反之亦然。
上面代码在模拟器中效果图大概就是这样子的啦:

《关于UILabel的属性与布局的一些体会》

UILabel固定宽度与高度的情况下

写一个固定宽高的UILabel,设置高度远大于文本高度时,文本在文本框中是垂直方向上居中显示的。

objectivec    UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(10, 20, 300, 100)];
    label.backgroundColor = [UIColor yellowColor];
    label.font = [UIFont systemFontOfSize:17.0f];
    label.text = @"当高度过高时,UILabel是居中显示的!!!";
    [self.view addSubview:label];

    UILabel *label2 = [[UILabel alloc]initWithFrame:CGRectMake(10, 220, 300, 100)];
    label2.backgroundColor = [UIColor yellowColor];
    label2.font = [UIFont systemFontOfSize:17.0f];
    label2.text = @"当高度过高时,UILabel是居中显示的!!!并且设置了多行显示";
    label2.numberOfLines = 0;
    [self.view addSubview:label2];

《关于UILabel的属性与布局的一些体会》文本框垂直方向居中

也正是因为这个原因,当我们调整UILabel的高度时,发现文本的位置也发生了上下偏移。
但通常开发中,我们希望可以控制文本在Y方向上的位置,那么高度就显得非常重要了。

情况二:通过文本内容与字体,计算文本的所需宽高!!!!!!!!!!!

iOS提供了通过文本的字体及内容,计算文本框所需宽高的方法。返回的CGSize是紧紧包围着文本内容的。
这样,我们就再也不需要去估计UILabel的宽高了,可以通过下面的方法,来根据内容和字体写文本框宽高。

具体是下面这样的:

objectivec    UILabel *label3 = [[UILabel alloc]init];
    label3.backgroundColor = [UIColor yellowColor];
    label3.font = [UIFont systemFontOfSize:17.0f];
    label3.text = @"根据文本框内容及字体,计算所需宽高";
    label3.numberOfLines = 0;
    //==================================================================================================================
    NSDictionary *attributeDic = @{NSFontAttributeName: [UIFont systemFontOfSize:17.0f]};
    CGSize constraintSize = CGSizeMake(100, CGFLOAT_MAX);
    CGSize realSize = [label3.text boundingRectWithSize:constraintSize 
                                                options:NSStringDrawingTruncatesLastVisibleLine|NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading  
                                             attributes:attributeDic 
                                                context:nil].size;

    [label3 setFrame:CGRectMake(10, 310, realSize.width, realSize.height)];
    //==================================================================================================================
    [self.view addSubview:label3];

上面的代码中,我们使用了下面的这个方法。

  • (CGRect)boundingRectWithSize:(CGSize)size options:(NSStringDrawingOptions)options attributes:(NSDictionary *)attributes context:(NSStringDrawingContext *)context

此方法可以返回,符合条件的bounding rect,也就是我们需要的CGRect对象,其中也就有我们需要的宽和高了。

《关于UILabel的属性与布局的一些体会》

当然了这个方法,还有一个姐妹方法,不过已经过期了,还是建议大家用这个方法来计算宽高。

《关于UILabel的属性与布局的一些体会》

    原文作者:enrecul101
    原文地址: https://segmentfault.com/a/1190000003055250
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞