UILabel 是我在第一次上手项目中,用得最多的一个控件。非常多的地方需要用它来显示文本信息。
通常需要绘制它的Frame、设置它的字体、颜色等等。最常见遇到的问题时,该如何去设置文本的大小以及位置,如果美工已经明确给出了视觉效果图,那么对于字体的大小,颜色都可以十分容易的进行设置了。而位置仍然是一个十分头疼的问题。
本文将主要就Text Attributes 和 Layout UILabel 来说一下我的体会。
Accessing the Text Attributes
首先,我们来看一下UILable的常见属性。
objectivec
UILabel *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的字体,还有更多其他的:
objectivec
NSString *const UIFontTextStyleHeadline;
NSString *const UIFontTextStyleSubheadline;
NSString *const UIFontTextStyleBody;
NSString *const UIFontTextStyleFootnote;
NSString *const UIFontTextStyleCaption1;
NSString *const UIFontTextStyleCaption2;
在不同位置使用不同的默认字体,这样是不是能够省去一些设计的麻烦呢。
当然我们也可以对获取到的默认格式字体,进行修改,下面的代码中,我向UIFontTextStyleBody中追加了加粗效果。
objectivec
UIFontDescriptor *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 时,以后设置的为准。
也就是说
objectivec
label.Text = @"aaaaa";
label.attributedText = @"bbbbb" ;
最后显示在界面上的,会是attributedText,反之亦然。
上面代码在模拟器中效果图大概就是这样子的啦:
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的高度时,发现文本的位置也发生了上下偏移。
但通常开发中,我们希望可以控制文本在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对象,其中也就有我们需要的宽和高了。
当然了这个方法,还有一个姐妹方法,不过已经过期了,还是建议大家用这个方法来计算宽高。